perm filename MCGRAW.XGP[LSP,JRA]3 blob
sn#262020 filedate 1977-02-01 generic text, type T, neo UTF8
/LMAR=0/XLINE=3/FONT#0=BASL30/FONT#1=BASB30/FONT#2=ASI30[LSP,JRA]/FONT#3=SUB/FONT#4=ASI30[LSP,JRA]/FONT#5=BASB30/FONT#6=GRK30/FONT#7=SUP/FONT#8=SPEC[LSP,JRA]/FONT#9=SET1/FONT#10=GRFX25[LSP,JRA]/FONT#11=FIX30/FONT#12=NGB30/FONT#13=GERM35/FONT#14=MG[LSP,JRA]/FONT#15=GRFX35
␈↓ ↓H␈↓␈↓↓␈↓ sCONTENTS i␈↓
␈↓ ↓H␈↓↓␈↓ ∧ZT A B L E O F C O N T E N T S
␈↓ ↓H␈↓↓CHAPTER␈↓ ¬PAGE␈↓
␈↓ ↓H␈↓␈↓ ↓x1␈↓ α8SYMBOLIC EXPRESSIONS␈↓ I1
␈↓ ↓H␈↓␈↓ βλ1.1␈↓ βhIntroduction␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ? 1
␈↓ ↓H␈↓␈↓ βλ1.2␈↓ βhSymbolic Expressions: Abstract Data Structures␈↓ λH . . . . . . . . . . . . . . ␈↓ ? 4
␈↓ ↓H␈↓␈↓ βλ1.3␈↓ βhTrees: Representations of Symbolic expressions␈↓ λH . . . . . . . . . . . . . . ␈↓ ? 7
␈↓ ↓H␈↓␈↓ βλ1.4␈↓ βhPrimitive Functions␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 10
␈↓ ↓H␈↓␈↓ βλ1.5␈↓ βhPredicates and Conditional Expressions␈↓ πh . . . . . . . . . . . . . . . . . ␈↓ 0 18
␈↓ ↓H␈↓␈↓ βλ1.6␈↓ βhSequences: Abstract Data Structures␈↓ π8 . . . . . . . . . . . . . . . . . . . ␈↓ 0 25
␈↓ ↓H␈↓␈↓ βλ1.7␈↓ βhLists: Representations of Sequences␈↓ π8 . . . . . . . . . . . . . . . . . . . ␈↓ 0 30
␈↓ ↓H␈↓␈↓ βλ1.8␈↓ βhA Respite␈↓ ∧h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 37
␈↓ ↓H␈↓␈↓ βλ1.9␈↓ βhBecoming an Expert␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 41
␈↓ ↓H␈↓␈↓ ↓x2␈↓ α8APPLICATIONS OF LISP␈↓ :50
␈↓ ↓H␈↓␈↓ βλ2.1␈↓ βhIntroduction␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 50
␈↓ ↓H␈↓␈↓ βλ2.2␈↓ βhExamples of LISP Applications␈↓ πλ . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 52
␈↓ ↓H␈↓␈↓ βλ2.3␈↓ βhDifferentiation␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 53
␈↓ ↓H␈↓␈↓ βλ2.4␈↓ βhData Bases␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 63
␈↓ ↓H␈↓␈↓ βλ2.5␈↓ βhAlgebra of Polynomials␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 68
␈↓ ↓H␈↓␈↓ βλ2.6␈↓ βhEvaluation of Polynomials␈↓ εX . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 73
␈↓ ↓H␈↓␈↓ βλ2.7␈↓ βhThe Great Mothers␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 83
␈↓ ↓H␈↓␈↓ βλ2.8␈↓ βhAnother Respite␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 84
␈↓ ↓H␈↓␈↓ βλ2.9␈↓ βhProving Properties of Programs␈↓ πλ . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 86
␈↓ ↓H␈↓␈↓ ↓x3␈↓ α8EVALUATION OF LISP EXPRESSIONS␈↓ :88
␈↓ ↓H␈↓␈↓ βλ3.1␈↓ βhIntroduction␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 88
␈↓ ↓H␈↓␈↓ βλ3.2␈↓ βhS-expr Translation of LISP Expressions␈↓ πh . . . . . . . . . . . . . . . . . ␈↓ 0 93
␈↓ ↓H␈↓␈↓ βλ3.3␈↓ βhSymbol Tables␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 96
␈↓ ↓H␈↓␈↓ βλ3.4␈↓ βh␈↓αλ␈↓-notation␈↓ ∧h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ 0 98
␈↓ ↓H␈↓␈↓ βλ3.5␈↓ βhMechanization of Evaluation␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 102
␈↓ ↓H␈↓␈↓ βλ3.6␈↓ βhExamples of ␈↓αeval␈↓␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 106
␈↓ ↓H␈↓␈↓ βλ3.7␈↓ βhVariables␈↓ ∧h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 114
␈↓ ↓H␈↓␈↓ βλ3.8␈↓ βhEnvironments and Bindings␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 116
␈↓ ↓H␈↓␈↓ βλ3.9␈↓ βh␈↓αlabel␈↓␈↓ ∧8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 121
␈↓ ↓H␈↓␈↓ βλ3.10␈↓ βhFunctional Arguments and Functional Values␈↓ λH . . . . . . . . . . . . . ␈↓ ! 123
␈↓ ↓H␈↓␈↓ βλ3.11␈↓ βhBinding Strategies and Implementations␈↓ πh . . . . . . . . . . . . . . . . ␈↓ ! 135
␈↓ ↓H␈↓␈↓ βλ3.12␈↓ βhSpecial Forms and Macros␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 140
␈↓ ↓H␈↓␈↓ βλ3.13␈↓ βhReview and Reflection␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 143
␈↓ ↓H␈↓␈↓↓ii CONTENTS␈↓ X␈↓
␈↓ ↓H␈↓␈↓ ↓x4␈↓ α8IMPERATIVE CONSTRUCTS IN LISP␈↓ +170
␈↓ ↓H␈↓␈↓ βλ4.1␈↓ βhIntroduction␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 170
␈↓ ↓H␈↓␈↓ βλ4.2␈↓ βhThe ␈↓αprog␈↓-feature␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 171
␈↓ ↓H␈↓␈↓ βλ4.3␈↓ βhAlternatives to ␈↓αprog␈↓␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 179
␈↓ ↓H␈↓␈↓ βλ4.4␈↓ βhExtensions to ␈↓αeval␈↓␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 182
␈↓ ↓H␈↓␈↓ βλ4.5␈↓ βhNon-recursive Control Structures␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 183
␈↓ ↓H␈↓␈↓ βλ4.6␈↓ βh␈↓αeval␈↓ with Explicit Access␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 185
␈↓ ↓H␈↓␈↓ βλ4.7␈↓ βh␈↓αeval␈↓ with Explicit Control␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 192
␈↓ ↓H␈↓␈↓ βλ4.8␈↓ βhAn Evaluator for ␈↓αprog␈↓␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 196
␈↓ ↓H␈↓␈↓ βλ4.9␈↓ βhAlternatives to ␈↓αeval␈↓␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 206
␈↓ ↓H␈↓␈↓ βλ4.10␈↓ βhFunction Definitions␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 210
␈↓ ↓H␈↓␈↓ βλ4.11␈↓ βhRapprochement: In Retrospect␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 213
␈↓ ↓H␈↓␈↓ βλ4.12␈↓ βhThe LISP Machine␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 222
␈↓ ↓H␈↓␈↓ ↓x5␈↓ α8IMPLEMENTATION OF THE STATIC STRUCTURE OF LISP␈↓ +225
␈↓ ↓H␈↓␈↓ βλ5.1␈↓ βhIntroduction␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 225
␈↓ ↓H␈↓␈↓ βλ5.2␈↓ βhRepresentation of S-expressions␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 226
␈↓ ↓H␈↓␈↓ βλ5.3␈↓ βhRepresentation of LISP Primitives␈↓ π8 . . . . . . . . . . . . . . . . . . ␈↓ ! 229
␈↓ ↓H␈↓␈↓ βλ5.4␈↓ βhAMBIT/G␈↓ ∧h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 234
␈↓ ↓H␈↓␈↓ βλ5.5␈↓ βhA Few Programming Techniques␈↓ π8 . . . . . . . . . . . . . . . . . . ␈↓ ! 235
␈↓ ↓H␈↓␈↓ βλ5.6␈↓ βhSymbol Tables and Property-lists␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 237
␈↓ ↓H␈↓␈↓ βλ5.7␈↓ βhProperty-list Functions␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 242
␈↓ ↓H␈↓␈↓ βλ5.8␈↓ βhAn ␈↓αeval␈↓ for Property-lists␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 243
␈↓ ↓H␈↓␈↓ βλ5.9␈↓ βhRepresentation of Property-lists␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 246
␈↓ ↓H␈↓␈↓ βλ5.10␈↓ βhA Picture of the Atom ␈↓αNIL␈↓␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 251
␈↓ ↓H␈↓␈↓ βλ5.11␈↓ βhInput/Output: ␈↓αread␈↓ and ␈↓αprint␈↓␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 252
␈↓ ↓H␈↓␈↓ βλ5.12␈↓ βhTable Searching: Hashing␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 256
␈↓ ↓H␈↓␈↓ βλ5.13␈↓ βhA First Look At ␈↓αcons␈↓␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 261
␈↓ ↓H␈↓␈↓ βλ5.14␈↓ βhStorage Management: Garbage Collection␈↓ λ_ . . . . . . . . . . . . . . . ␈↓ ! 263
␈↓ ↓H␈↓␈↓ βλ5.15␈↓ βhA Simple LISP Garbage Collector␈↓ π8 . . . . . . . . . . . . . . . . . . ␈↓ ! 264
␈↓ ↓H␈↓␈↓ βλ5.16␈↓ βhA Review of the Structure of the LISP Machine␈↓ λx . . . . . . . . . . . ␈↓ ! 269
␈↓ ↓H␈↓␈↓ βλ5.17␈↓ βhImplementations of Binding␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 269
␈↓ ↓H␈↓␈↓ βλ5.18␈↓ βhStack Implementation of Deep Binding␈↓ πh . . . . . . . . . . . . . . . . ␈↓ ! 272
␈↓ ↓H␈↓␈↓ βλ5.19␈↓ βhStack Implementation of Shallow Binding␈↓ λ_ . . . . . . . . . . . . . . . ␈↓ ! 273
␈↓ ↓H␈↓␈↓ βλ5.20␈↓ βhStrategies for LISP Implementation␈↓ π8 . . . . . . . . . . . . . . . . . . ␈↓ ! 280
␈↓ ↓H␈↓␈↓ βλ5.21␈↓ βhEpilogue␈↓ ∧h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 281
␈↓ ↓H␈↓␈↓ ↓x6␈↓ α8THE DYNAMIC STRUCTURE OF LISP␈↓ +283
␈↓ ↓H␈↓␈↓ βλ6.1␈↓ βhIntroduction␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 283
␈↓ ↓H␈↓␈↓ βλ6.2␈↓ βhPrimitives for LISP␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 287
␈↓ ↓H␈↓␈↓ βλ6.3␈↓ βh␈↓ SM␈↓: A Simple Machine␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 290
␈↓ ↓H␈↓␈↓ βλ6.4␈↓ βhImplementation of the Primitives␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 294
␈↓ ↓H␈↓␈↓ βλ6.5␈↓ βhAssemblers␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 298
␈↓ ↓H␈↓␈↓↓␈↓ aCONTENTS iii␈↓
␈↓ ↓H␈↓␈↓ βλ6.6␈↓ βhCompilers for Subsets of LISP␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 300
␈↓ ↓H␈↓␈↓ βλ6.7␈↓ βhCompilation of Conditional Expressions␈↓ πh . . . . . . . . . . . . . . . . ␈↓ ! 303
␈↓ ↓H␈↓␈↓ βλ6.8␈↓ βhOne-pass Assemblers and Fixups␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 307
␈↓ ↓H␈↓␈↓ βλ6.9␈↓ βhCompiling and Interpreting␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 310
␈↓ ↓H␈↓␈↓ βλ6.10␈↓ βhA compiler for Simple ␈↓αeval␈↓: The Value Stack␈↓ λH . . . . . . . . . . . . . ␈↓ ! 314
␈↓ ↓H␈↓␈↓ βλ6.11␈↓ βhA Compiler for Simple ␈↓αeval␈↓␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 317
␈↓ ↓H␈↓␈↓ βλ6.12␈↓ βhEfficient Compilation␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 322
␈↓ ↓H␈↓␈↓ βλ6.13␈↓ βhEfficiency: Primitive Operations␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 323
␈↓ ↓H␈↓␈↓ βλ6.14␈↓ βhEfficiency: Calling Sequences␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 325
␈↓ ↓H␈↓␈↓ βλ6.15␈↓ βhEfficiency: Predicates␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 329
␈↓ ↓H␈↓␈↓ βλ6.16␈↓ βhA Compiler for ␈↓αprogs␈↓␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 331
␈↓ ↓H␈↓␈↓ βλ6.17␈↓ βhFurther Optimizations␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 333
␈↓ ↓H␈↓␈↓ βλ6.18␈↓ βhFunctional Arguments␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 335
␈↓ ↓H␈↓␈↓ βλ6.19␈↓ βhMacros and Special Forms␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 336
␈↓ ↓H␈↓␈↓ βλ6.20␈↓ βhCompilation and Variables␈↓ εX . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 338
␈↓ ↓H␈↓␈↓ βλ6.21␈↓ βhInteractive Programming␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 339
␈↓ ↓H␈↓␈↓ βλ6.22␈↓ βhLISP Editors␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 342
␈↓ ↓H␈↓␈↓ βλ6.23␈↓ βhDebugging in LISP␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 344
␈↓ ↓H␈↓␈↓ ↓x7␈↓ α8STORAGE STRUCTURES AND EFFICIENCY␈↓ +347
␈↓ ↓H␈↓␈↓ βλ7.1␈↓ βhBit-tables␈↓ ∧h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 347
␈↓ ↓H␈↓␈↓ βλ7.2␈↓ βhVectors and Arrays␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 348
␈↓ ↓H␈↓␈↓ βλ7.3␈↓ βhStrings and Linear LISP␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 351
␈↓ ↓H␈↓␈↓ βλ7.4␈↓ βhA Compacting Collector for LISP␈↓ π8 . . . . . . . . . . . . . . . . . . ␈↓ ! 353
␈↓ ↓H␈↓␈↓ βλ7.5␈↓ βhRepresentations of Complex Data Structures␈↓ λH . . . . . . . . . . . . . ␈↓ ! 357
␈↓ ↓H␈↓␈↓ βλ7.6␈↓ βh␈↓αrplaca␈↓ and ␈↓αrplacd␈↓␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 358
␈↓ ↓H␈↓␈↓ βλ7.7␈↓ βhApplications of ␈↓αrplaca␈↓ and ␈↓αrplacd␈↓␈↓ π8 . . . . . . . . . . . . . . . . . . ␈↓ ! 361
␈↓ ↓H␈↓␈↓ βλ7.8␈↓ βhNumbers␈↓ ∧h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 364
␈↓ ↓H␈↓␈↓ βλ7.9␈↓ βhStacks and Threading␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 368
␈↓ ↓H␈↓␈↓ βλ7.10␈↓ βhA Non-recursive ␈↓αread␈↓␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 369
␈↓ ↓H␈↓␈↓ βλ7.11␈↓ βhMore Applications of Threading␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 373
␈↓ ↓H␈↓␈↓ βλ7.12␈↓ βhStorage Management and LISP␈↓ πλ . . . . . . . . . . . . . . . . . . . . ␈↓ ! 373
␈↓ ↓H␈↓␈↓ βλ7.13␈↓ βhHash Techniques␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 377
␈↓ ↓H␈↓␈↓ ↓x8␈↓ α8IMPLICATIONS OF LISP␈↓ +379
␈↓ ↓H␈↓␈↓ ↓x9␈↓ α8PROJECTS␈↓ +386
␈↓ ↓H␈↓␈↓ βλ9.1␈↓ βhExtensions to ␈↓αeval␈↓␈↓ ¬H . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 386
␈↓ ↓H␈↓␈↓ βλ9.2␈↓ βhPretty-printing␈↓ ¬_ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 388
␈↓ ↓H␈↓␈↓ βλ9.3␈↓ βhSyntax-directed Processes␈↓ ε( . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 391
␈↓ ↓H␈↓␈↓ βλ9.4␈↓ βhSyntax-directed I/O␈↓ ¬x . . . . . . . . . . . . . . . . . . . . . . . . . . ␈↓ ! 396
␈↓ ↓H␈↓␈↓↓iv CONTENTS␈↓ X␈↓
␈↓ ↓H␈↓␈↓ ↓xBIBLIOGRAPHY␈↓ +401
␈↓ ↓H␈↓␈↓ ↓xINDEX␈↓ +415
␈↓ ↓H␈↓␈↓↓1.␈↓ λuSymbolic expressions 1␈↓
␈↓ ↓H␈↓␈↓ ¬y␈↓↓CHAPTER 1
␈↓ ↓H␈↓↓␈↓ ¬∂SYMBOLIC EXPRESSIONS␈↓
␈↓ ↓H␈↓␈↓ ¬a␈↓↓1.1 Introduction␈↓
␈↓ ↓H␈↓This␈αbook␈αis␈α
a␈αstudy␈αof␈α
data␈αstructures␈αand␈αprogramming␈α
languages;␈αin␈αparticular␈α
it␈αis␈αa␈α
study␈αof
␈↓ ↓H␈↓data␈α
structures␈αand␈α
programming␈αlanguages␈α
centered␈αaround␈α
the␈αlanguage␈α
LISP.␈αHowever,␈α
this␈αis
␈↓ ↓H␈↓not␈αa␈αmanual␈αto␈αhelp␈αyou␈αbecome␈αa␈αproficient␈αLISP␈αcoder.␈α We␈αwill␈αstudy␈αmany␈αof␈αthe␈αformal␈αand
␈↓ ↓H␈↓theoretical␈αaspects␈αof␈αlanguages␈αand␈αdata␈αstructures␈αas␈αwell␈αas␈αexamining␈αthe␈αpractical␈αapplications
␈↓ ↓H␈↓of␈α
data␈α
structures.␈α
We␈α
will␈α
show␈α
that␈α
this␈α
area␈α
of␈α
computer␈α
science␈α
is␈α
a␈α
discipline␈α
of␈α
importance␈α
and
␈↓ ↓H␈↓beauty,␈α
worthy␈αof␈α
careful␈α
study.␈α How␈α
are␈α
we␈αto␈α
proceed?␈α
How␈αdo␈α
we␈α
introduce␈αrigor␈α
into␈α
a␈αfield
␈↓ ↓H␈↓whose␈αcountenance␈αis␈αas␈α␈↓αad␈αhoc␈↓␈αand␈αdiverse␈αas␈αthat␈αof␈αprogramming?␈α We␈αmust␈αbear␈αin␈αmind␈αthat
␈↓ ↓H␈↓the␈αresults␈αof␈αour␈αstudies␈αare␈αto␈αhave␈αpractical␈αapplications.␈α We␈αmust␈αnot␈αpursue␈αtheory␈αand␈αrigor
␈↓ ↓H␈↓without␈α
proper␈αregard␈α
for␈α
practice.␈αOur␈α
study␈αis␈α
not␈α
that␈αof␈α
pure␈α
mathematics;␈αour␈α
results␈αwill␈α
have
␈↓ ↓H␈↓applications␈α
in␈α
everyday␈α∞programming␈α
practice.␈α
However,␈α
for␈α∞guidance␈α
let's␈α
look␈α∞at␈α
mathematics.
␈↓ ↓H␈↓Here␈α∩is␈α∩a␈α∩well-established␈α∩discipline␈α∩rich␈α∩in␈α⊃history␈α∩and␈α∩full␈α∩of␈α∩results␈α∩of␈α∩both␈α∩practical␈α⊃and
␈↓ ↓H␈↓theoretical importance.
␈↓ ↓H␈↓One␈α
of␈α
the␈α
more␈α
fertile,␈α
yet␈α
easily␈αintroduced␈α
areas␈α
of␈α
mathematics,␈α
is␈α
that␈α
of␈α
elementary␈αnumber
␈↓ ↓H␈↓theory.␈α⊃It␈α⊃is␈α∩easy␈α⊃to␈α⊃introduce␈α∩because␈α⊃everyone␈α⊃knows␈α∩something␈α⊃about␈α⊃the␈α∩natural␈α⊃numbers.
␈↓ ↓H␈↓Number␈α⊃theory␈α⊃studies␈α⊃properties␈α⊃of␈α⊂a␈α⊃certain␈α⊃class␈α⊃of␈α⊃operations␈α⊂definable␈α⊃over␈α⊃the␈α⊃set␈α⊃␈↓N␈↓␈α⊂of
␈↓ ↓H␈↓non-negative␈αintegers␈αalso␈αcalled␈αnatural␈αnumbers.␈α A␈αvery␈αformal␈αpresentation␈αmight␈αbegin␈αwith␈αa
␈↓ ↓H␈↓construction␈αof␈α␈↓N␈↓␈αfrom␈αmore␈αprimitive␈αnotions,␈αbut␈αit␈αis␈αusually␈αassumed␈αthat␈αthe␈αreader␈αis␈α
familiar
␈↓ ↓H␈↓with␈αthe␈αfundamental␈αproperties␈αof␈α␈↓N␈↓.␈α In␈αeither␈αcase␈αthe␈αnext␈αstep␈αwould␈αbe␈αto␈αdefine␈αthe␈αclass␈αof
␈↓ ↓H␈↓operations which we would allow on our domain.
␈↓ ↓H␈↓We␈α∞shall␈α∞begin␈α∞our␈α
study␈α∞of␈α∞LISP␈α∞in␈α∞a␈α
similar␈α∞manner,␈α∞as␈α∞an␈α
investigation␈α∞of␈α∞a␈α∞certain␈α∞class␈α
of
␈↓ ↓H␈↓operations␈αdefinable␈α
over␈αa␈αdomain␈α
of␈αobjects,␈αcalled␈α
Symbolic␈αExpressions.␈α Though␈α
most␈αpeople
␈↓ ↓H␈↓know␈α∂something␈α∂about␈α∂the␈α∂natural␈α∂numbers,␈α∂we␈α∂are␈α∂perhaps␈α∂not␈α∂so␈α∂fortunate␈α∂when␈α∂it␈α∂comes␈α∂to
␈↓ ↓H␈↓Symbolic␈α∩expressions.␈α∩We␈α∩must␈α∩define␈α∩what␈α∪we␈α∩mean␈α∩by␈α∩"symbolic␈α∩expression".␈α∩Let's␈α∪look␈α∩to
␈↓ ↓H␈↓mathematics␈α
again␈α
for␈α
help.␈α
If␈αwe␈α
asked␈α
someone␈α
to␈α
define␈αthe␈α
domain␈α
␈↓N␈↓␈↓π 1␈↓,␈α
the␈α
definition␈αwe␈α
would
␈↓ ↓H␈↓receive␈α⊃would␈α⊃depend␈α⊃on␈α⊃how␈α⊃familar␈α⊃that␈α⊃individual␈α⊃was␈α⊃with␈α⊃the␈α⊃properties␈α⊃of␈α⊃the␈α⊃natural
␈↓ ↓H␈↓numbers.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 1␈↓␈αWe␈αwill␈α
not␈αattempt␈αto␈α
arrive␈αat␈αa␈α
completely␈αself-contained␈αdefinition␈α
of␈α"natural␈αnumber".␈α
That
␈↓ ↓H␈↓is␈α∪a␈α∪difficult␈α∪undertaking.␈α∪See␈α∪[Goo 57].␈α∪We␈α∪will␈α∪be␈α∪satisfied␈α∪with␈α∪discussing␈α∪␈↓↓some␈↓␈α∀of␈α∪their
␈↓ ↓H␈↓characteristics.
␈↓ ↓H␈↓␈↓↓2 Symbolic expressions␈↓ 91.1␈↓
␈↓ ↓H␈↓For␈α∀most␈α∀people␈α∃and␈α∀most␈α∀purposes,␈α∃the␈α∀following␈α∀characterization␈α∃of␈α∀a␈α∀natural␈α∃number␈α∀is
␈↓ ↓H␈↓satisfactory:
␈↓ ↓H␈↓␈↓ I:␈↓␈↓ αXA natural number is a sequence of decimal digits.
␈↓ ↓H␈↓The␈α
definition␈α
assumes␈α
the␈α
terminology␈α
of␈α
"sequence",␈α"decimal"␈α
and␈α
"digit"␈α
are␈α
known.␈α
If␈α
any␈αof
␈↓ ↓H␈↓these␈α⊗terms␈α⊗are␈α⊗␈↓↓not␈↓␈α⊗understood,␈α⊗they␈α∃can␈α⊗be␈α⊗further␈α⊗elaborated.␈α⊗However,␈α⊗this␈α⊗process␈α∃of
␈↓ ↓H␈↓explanation␈α
and␈α
description␈α
must␈αterminate.␈α
We␈α
must␈α
assume␈αthat␈α
some␈α
concepts␈α
require␈αno␈α
further
␈↓ ↓H␈↓elaboration.␈α∀The␈α∀current␈α∀definition␈α∃suffers␈α∀from␈α∀a␈α∀different␈α∃kind␈α∀of␈α∀inadequacy.␈α∀It␈α∃fails␈α∀to
␈↓ ↓H␈↓illuminate␈α∞the␈α∞relationships␈α
between␈α∞natural␈α∞numbers.␈α
The␈α∞"meaning"␈α∞of␈α
the␈α∞natural␈α∞numbers␈α
is
␈↓ ↓H␈↓missing.␈αIt␈αis␈αlike␈αgiving␈αa␈αperson␈αan␈α
alphabet␈αand␈αrules␈αfor␈αforming␈αsyntactically␈αcorrect␈αwords␈α
but
␈↓ ↓H␈↓not supplying a dictionary which relates these words to the person's vocabulary.
␈↓ ↓H␈↓If pressed for details we might attempt a more elaborate characterization like the following:
␈↓ ↓H␈↓␈↓ β(␈↓↓1.␈↓ ␈↓αzero␈↓ is an element of ␈↓N␈↓.
␈↓ ↓H␈↓␈↓ II:␈↓␈↓ β(␈↓↓2.␈↓ If ␈↓αn␈↓ is in ␈↓N␈↓ then the ␈↓αsuccessor␈↓ of ␈↓αn␈↓ is in ␈↓N␈↓.
␈↓ ↓H␈↓␈↓ β(␈↓↓3.␈↓ The only elements of ␈↓N␈↓ are those created by finitely many applications
␈↓ ↓H␈↓␈↓ β(of rules ␈↓↓1␈↓ and ␈↓↓2␈↓.
␈↓ ↓H␈↓Definition␈α
␈↓ II␈↓␈αappears␈α
to␈α
be␈αcompletely␈α
at␈α
the␈αother␈α
end␈α
of␈αthe␈α
spectrum;␈α
it␈αtells␈α
us␈α
very␈αlittle␈α
about
␈↓ ↓H␈↓the␈αappearance␈αof␈αthe␈αintegers.␈αIt␈αgives␈αus␈αan␈αinitial␈αelement␈α␈↓αzero␈↓␈αand␈αan␈αoperation␈αcalled␈α␈↓αsuccessor␈↓,
␈↓ ↓H␈↓which␈αis␈αto␈αexhibit␈αa␈αnew␈αelement,␈αgiven␈αan␈αold␈αone.␈α Unless␈αwe␈αare␈αcareful␈αabout␈αthe␈αmeaning␈αof
␈↓ ↓H␈↓␈↓αsuccessor␈↓,␈α∞definition␈α∞␈↓ II␈↓␈α∞will␈α∞be␈α∞inadequate.␈α∞For␈α∞example␈α∞if␈α∞we␈α∞define␈α∞the␈α∞successor␈α∞of␈α∞a␈α
natural
␈↓ ↓H␈↓number to be that same number then ␈↓ II␈↓ is satisfied but unsatisfactory.
␈↓ ↓H␈↓We␈α
can␈αdefine␈α
␈↓αsuccessor␈↓␈α
as␈αa␈α
specific␈α
mapping,␈α␈↓↓S␈↓,␈α
which␈αcreates␈α
new␈α
elements␈αsubject␈α
to␈α
the␈αrules
␈↓ ↓H␈↓that␈α
two␈α∞elements,␈α
␈↓αx␈↓␈α∞and␈α
␈↓αy␈↓␈α
are␈α∞equal␈α
just␈α∞in␈α
the␈α∞case␈α
that␈α
␈↓↓S␈↓α(x)␈↓␈α∞equals␈α
␈↓↓S␈↓α(y)␈↓;␈α∞and␈α
␈↓↓S␈↓α(x)␈↓␈α∞is␈α
different
␈↓ ↓H␈↓from␈α⊃␈↓αx␈↓,␈α⊃for␈α⊃any␈α⊃element␈α⊃␈↓αx␈↓.␈α⊃ We␈α⊃select␈α⊃a␈α⊃distinguished␈α⊃element,␈α⊃␈↓α0␈↓,␈α⊃as␈α⊃a␈α⊃notation␈α⊃for␈α⊃␈↓αzero␈↓;␈α⊃and
␈↓ ↓H␈↓abbreviate ␈↓↓S␈↓α(0)␈↓↓, as ␈↓α1␈↓, etc. in the usual manner.
␈↓ ↓H␈↓The␈αcharacterization␈αof␈αdecimal␈αdigits␈αgiven␈αin␈α␈↓ I␈↓␈αis␈αsyntactic.␈α The␈αnotation␈αitself␈αtells␈α
us␈αnothing
␈↓ ↓H␈↓about␈α
the␈α
interrelationships␈α
between␈α
the␈α
numbers,␈α
but␈α
it␈α
does␈α
give␈α
us␈α
a␈α
notation␈α∞for␈α
representing
␈↓ ↓H␈↓them.␈α
Thus␈α␈↓α2␈↓␈α
can␈α
be␈αused␈α
to␈αrepresent␈α
␈↓αtwo␈↓␈α
or␈αused␈α
as␈αan␈α
abbreviation␈α
for␈α␈↓↓S␈↓α(␈↓↓S␈↓α(0))␈↓.␈α
One␈αbenefit␈α
of
␈↓ ↓H␈↓the␈α
␈↓↓S␈↓-notation␈α
is␈α
that␈α
it␈α
explicitly␈α
shows␈α
the␈α
means␈α
of␈α
construction.␈α
That␈α
is,␈α
it␈α
shows␈α
more␈α
of␈α
the
␈↓ ↓H␈↓properties␈αof␈αthese␈αnumbers␈αthan␈αjust␈αdistinguishability.␈α We␈αshall␈αrefer␈αto␈αthe␈αdigit␈αrepresentation
␈↓ ↓H␈↓as␈α␈↓↓numerals␈↓␈α
and␈αreserve␈αthe␈α
term,␈α␈↓↓natural␈αnumber␈↓,␈α
for␈αthe␈αabstract␈α
object.␈α Thus␈αnumerals␈α
denote,
␈↓ ↓H␈↓stand␈αfor,␈αor␈αrepresent␈αthe␈αabstract␈αobjects␈α
called␈αnatural␈αnumbers;␈αand␈αdefinition␈α␈↓ I␈↓␈αis␈αbetter␈α
stated
␈↓ ↓H␈↓as: "a natural number can be represented as a finite sequence of digits".
␈↓ ↓H␈↓But␈αnotation␈αand␈αsyntax␈αare␈αnecessary␈αand␈αwe␈α
must␈αbe␈αable␈αto␈αgive␈αprecise␈αdescriptions␈αof␈α
syntactic
␈↓ ↓H␈↓notions.␈α
Given␈α
a␈α∞choice␈α
between␈α
the␈α
two␈α∞previous␈α
definitions,␈α
␈↓ I␈↓␈α
and␈α∞␈↓ II␈↓,␈α
it␈α
appears␈α
that␈α∞␈↓ II␈↓␈α
is
␈↓ ↓H␈↓more␈α∂precise.␈α∂ Much␈α∂less␈α∂is␈α∂left␈α∂to␈α∂the␈α∞imagination;␈α∂given␈α∂␈↓αzero␈↓␈α∂and␈α∂a␈α∂definition␈α∂of␈α∂␈↓αsuccessor␈↓␈α∞the
␈↓ ↓H␈↓␈↓↓1.1␈↓ mIntroduction 3␈↓
␈↓ ↓H␈↓definition␈α∂will␈α∞act␈α∂as␈α∞a␈α∂recipe␈α∂for␈α∞producing␈α∂elements␈α∞of␈α∂␈↓N␈↓.␈α∂This␈α∞style␈α∂of␈α∞definition␈α∂is␈α∂called␈α∞an
␈↓ ↓H␈↓inductive definition or generative definition.
␈↓ ↓H␈↓The basic content of an inductive definition of a set of objects consists of three parts:
␈↓ ↓H␈↓␈↓ αh(1)␈α∂A␈α∂description␈α∂of␈α∂an␈α∂initial␈α∂set␈α∂of␈α∂objects;␈α∂the␈α∂elements␈α∂of␈α∂this␈α∂set␈α∂are␈α⊂the␈α∂initial
␈↓ ↓H␈↓␈↓ αhelements of the set we are describing in the inductive definition.
␈↓ ↓H␈↓␈↓ IND␈↓
␈↓ ↓H␈↓␈↓ αh(2)␈αGiven␈αthe␈αdescription␈αof␈αsome␈αexisting␈αelements␈α
in␈αthe␈αset,␈αwe␈αare␈αgiven␈αa␈αmeans␈α
of
␈↓ ↓H␈↓␈↓ αhconstructing more elements.
␈↓ ↓H␈↓␈↓ αh(3)␈α⊃A␈α⊂termination␈α⊃clause,␈α⊂saying␈α⊃that␈α⊂the␈α⊃only␈α⊂elements␈α⊃in␈α⊂the␈α⊃set␈α⊂are␈α⊃those␈α⊂which
␈↓ ↓H␈↓␈↓ αhgained admittance by either (1) or (2).
␈↓ ↓H␈↓Notice␈α∂that␈α∂our␈α∂definition␈α⊂of␈α∂␈↓N␈↓,␈α∂in␈α∂terms␈α⊂of␈α∂␈↓αzero␈↓␈α∂and␈α∂␈↓αsuccessor␈↓,␈α∂is␈α⊂an␈α∂instance␈α∂of␈α∂␈↓ IND␈↓:␈α⊂we␈α∂are
␈↓ ↓H␈↓defining␈α
the␈α
set␈αof␈α
natural␈α
numbers:␈α␈↓αzero␈↓␈α
is␈α
initially␈αincluded␈α
in␈α
the␈αset;␈α
then␈α
applying␈α
the␈αsecond
␈↓ ↓H␈↓phrase of the definition we can say that ␈↓αone␈↓ is in the set since ␈↓αone␈↓ is the successor of ␈↓αzero␈↓.
␈↓ ↓H␈↓We can recast the positional notation description as an inductive definition.
␈↓ ↓H␈↓␈↓ β(␈↓↓1.␈↓ A numeral is a digit
␈↓ ↓H␈↓␈↓ β(␈↓↓2.␈↓ If ␈↓αn␈↓ is a numeral then ␈↓αn␈↓ followed by a digit is a numeral.
␈↓ ↓H␈↓␈↓ β(␈↓↓3.␈↓ The only numerals are those created by finitely many applications of ␈↓↓1␈↓ and ␈↓↓2␈↓.
␈↓ ↓H␈↓In words, "a numeral is a digit, or a numeral followed by a digit".
␈↓ ↓H␈↓In␈α∂this␈α∂application␈α⊂of␈α∂␈↓ IND␈↓,␈α∂the␈α⊂initial␈α∂set␈α∂has␈α⊂more␈α∂than␈α∂one␈α⊂element;␈α∂namely␈α∂the␈α⊂ten␈α∂decimal
␈↓ ↓H␈↓digits.␈α Again,␈αwe␈αassume␈αthat␈αthe␈αquestioner␈αknows␈αwhat␈α"digit"␈αmeans.␈α This␈αis␈αa␈αcharacteristic␈αof
␈↓ ↓H␈↓all␈α∪definitions:␈α∪we␈α∪must␈α∪stop␈α∪␈↓↓somewhere␈↓␈α∪in␈α∪our␈α∪explication.␈α∪Notice␈α∪too␈α∪that␈α∪we␈α∪assume␈α∪that
␈↓ ↓H␈↓"followed by" means juxtaposition.
␈↓ ↓H␈↓Inductive␈α∞definitions␈α∞have␈α
been␈α∞the␈α∞province␈α
of␈α∞mathematics␈α∞for␈α
many␈α∞years;␈α∞however,␈α
computer
␈↓ ↓H␈↓science␈α∂has␈α∂developed␈α∂a␈α∂style␈α∂of␈α∂syntax␈α∂specification␈α∂called␈α∂BNF␈α∂(Backus-Naur␈α∂Form)␈α∂equations
␈↓ ↓H␈↓which␈α∪has␈α∪the␈α∪same␈α∪intent␈α∪as␈α∪that␈α∪of␈α∪inductive␈α∪definitions.␈α∪ Here␈α∪is␈α∪the␈α∀previous␈α∪inductive
␈↓ ↓H␈↓definition of "numeral" as a set of BNF equations:
␈↓ ↓H␈↓<numeral>␈↓ β(::= <digit>
␈↓ ↓H␈↓<numeral>␈↓ β(::= <numeral><digit>
␈↓ ↓H␈↓As an abbreviation, the two BNF equations may also be written:
␈↓ ↓H␈↓<numeral>␈↓ β(::= <digit> | <numeral><digit>.
␈↓ ↓H␈↓␈↓↓4 Symbolic expressions␈↓ 91.1␈↓
␈↓ ↓H␈↓A␈α
comparison␈α
between␈αthe␈α
BNF␈α
and␈αthe␈α
inductive␈α
descriptions␈αof␈α
"numeral"␈α
should␈α
clarify␈αmuch
␈↓ ↓H␈↓of␈αthe␈αnotation,␈αbut␈αwe␈αwill␈αgive␈αa␈αmore␈αdetailed␈αanalysis.␈α The␈αsymbol␈α"::="␈αmay␈αbe␈αread␈α"is␈αa",␈αthe
␈↓ ↓H␈↓symbol␈α⊃"|"␈α∩may␈α⊃be␈α∩read␈α⊃"or".␈α∩ The␈α⊃character␈α∩strings␈α⊃beginning␈α∩with␈α⊃"<"␈α∩and␈α⊃ending␈α∩with␈α⊃">"
␈↓ ↓H␈↓correspond␈α⊂to␈α⊂"numeral"␈α⊂and␈α⊂"digit"␈α⊂in␈α⊂␈↓↓1␈↓␈α⊂and␈α⊂␈↓↓2␈↓;␈α⊂by␈α⊂convention,␈α⊂components␈α⊂of␈α⊃BNF␈α⊂equations
␈↓ ↓H␈↓which␈α␈↓↓describe␈↓␈αelements␈α
are␈αenclosed␈αin␈α"<"␈α
and␈α">";␈αand␈αelements␈α
which␈αare␈αgiven␈α
␈↓↓explicitly␈↓␈αare
␈↓ ↓H␈↓written␈αwithout␈αthe␈α"<␈α>"␈αfence.␈α Thus␈α"<digit>"␈αis␈αnot␈αa␈αnumeral␈αbut␈αis␈αa␈αdescription;␈αto␈αmake␈αthe
␈↓ ↓H␈↓definition of <numeral> complete we should include an equation like:
␈↓ ↓H␈↓<digit>␈↓ β(:: = ␈↓α0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9␈↓
␈↓ ↓H␈↓Juxtaposition␈αof␈αobjects␈αimplies␈α
concatenation␈αof␈αthe␈αsyntactic␈αobjects.␈α
Thus␈α"89"␈αis␈αan␈α
instance␈αof
␈↓ ↓H␈↓"<numeral><digit>".
␈↓ ↓H␈↓It␈αwill␈αbe␈αconvenient␈αto␈αhave␈αnotations␈αfor␈αthe␈αabstract␈αobjects␈αas␈αwell␈αas␈αnotations␈αfor␈αthe␈α
syntactic
␈↓ ↓H␈↓representations.␈α∂The␈α∂BNF␈α∂equations␈α∂describe␈α∂syntactic␈α∞classes;␈α∂for␈α∂example,␈α∂the␈α∂set␈α∂generated␈α∞by
␈↓ ↓H␈↓<numeral>␈α∂is␈α⊂the␈α∂syntactic␈α⊂class␈α∂of␈α⊂numerals␈↓π 2␈↓.␈α∂ When␈α⊂we␈α∂are␈α⊂talking␈α∂about␈α⊂a␈α∂syntactic␈α⊂class␈α∂of
␈↓ ↓H␈↓objects␈α∪we␈α∪will␈α∪write␈α∪<object>;␈α∪when␈α∪we␈α∩are␈α∪talking␈α∪about␈α∪the␈α∪abstract␈α∪object␈α∪we␈α∪will␈α∩write
␈↓ ↓H␈↓␈↓<object>␈↓. For example ␈↓<numeral>␈↓ is the class of natural numbers.
␈↓ ↓H␈↓What␈α∪should␈α∩be␈α∪remembered␈α∩from␈α∪the␈α∪discussion␈α∩in␈α∪this␈α∩section?␈α∪ We␈α∩need␈α∪precise␈α∪ways␈α∩of
␈↓ ↓H␈↓describing␈α
the␈α
elements␈α
of␈α
our␈α
study␈α
on␈αdata␈α
structures.␈α
We␈α
have␈α
seen␈α
that␈α
inductive␈αdefinitions␈α
are
␈↓ ↓H␈↓a␈αpowerful␈α
way␈αof␈α
describing␈αsets␈α
of␈αobjects.␈αWe␈α
have␈αseen␈α
a␈αvariant␈α
of␈αinductive␈αdefinitions␈α
called
␈↓ ↓H␈↓Backus-Naur␈α⊃Form␈α⊂equations.␈α⊃We␈α⊃will␈α⊂use␈α⊃BNF␈α⊃equations␈α⊂to␈α⊃describe␈α⊃the␈α⊂syntax␈α⊃of␈α⊃our␈α⊂data
␈↓ ↓H␈↓structures and our language.
␈↓ ↓H␈↓We␈α
have␈α∞also␈α
introduced␈α
the␈α∞difference␈α
between␈α
an␈α∞abstract␈α
object␈α
and␈α∞a␈α
representation␈α∞for␈α
that
␈↓ ↓H␈↓object.␈α This␈αdistinction␈αhas␈αbeen␈α
well␈αstudied␈αin␈αphilosophy␈αand␈α
mathematics,␈αand␈αwe␈αwill␈αsee␈α
that
␈↓ ↓H␈↓this␈α∞idea␈α∂has␈α∞strong␈α∞consequences␈α∂for␈α∞the␈α∂field␈α∞of␈α∞programming␈α∂and␈α∞computer␈α∂science.␈α∞ Abstract
␈↓ ↓H␈↓objects and their representations will play crucial roles in this text.
␈↓ ↓H␈↓␈↓ βr␈↓↓1.2 Symbolic Expressions: Abstract Data Structures␈↓
␈↓ ↓H␈↓We␈α
wish␈αto␈α
show␈α
that␈αthe␈α
use␈α
of␈αabstraction␈α
will␈α
benefit␈αthe␈α
study␈α
of␈αdata␈α
structures␈α
and␈αLISP.␈α
To
␈↓ ↓H␈↓begin␈αour␈αstudy␈αwe␈αshould␈αtherefore␈αcharacterize␈αthe␈αdomain␈αof␈αLISP␈αdata␈αstructures␈αin␈αa␈αmanner
␈↓ ↓H␈↓similar to what we did for numbers.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 2␈↓␈α∂Note␈α∂we␈α∂could␈α∂have␈α∂written␈α∂<numeral> ::= <digit> | <digit><numeral>␈α∂and␈α∂generated␈α∂the␈α∂same
␈↓ ↓H␈↓class,␈αbut␈αin␈αa␈αdifferent␈αorder.␈αQuestions␈αof␈αsyntax␈αand␈αgrammars␈αwill␈αnot␈αbe␈αstressed␈αin␈αthis␈αbook.
␈↓ ↓H␈↓See [Aho 72].
␈↓ ↓H␈↓␈↓↓1.2␈↓ ε⊂Symbolic Expressions: Abstract Data Structures 5␈↓
␈↓ ↓H␈↓Our␈α∂objects␈α⊂are␈α∂called␈α⊂␈↓↓Symbolic␈α∂Expressions␈↓.␈α∂ Our␈α⊂domain␈α∂of␈α⊂Symbolic␈α∂Expressions␈α⊂is␈α∂named
␈↓ ↓H␈↓␈↓<sexpr>␈↓. Symbolic expressions are also known as ␈↓¬S-expressions␈↓ or ␈↓¬S-exprs␈↓.
␈↓ ↓H␈↓The␈α∂set␈α∂of␈α∞symbolic␈α∂expressions␈α∂is␈α∞defined␈α∂inductively␈α∂over␈α∞a␈α∂base␈α∂set␈α∞named␈α∂␈↓<atom>␈↓.␈α∂The␈α∞set
␈↓ ↓H␈↓␈↓<atom>␈↓␈αcan␈αitself␈αbe␈αdefined␈αinductively.␈αWe␈αgive␈αa␈αset␈αof␈αBNF␈αequations␈αfor␈αelements␈αof␈α<atom>
␈↓ ↓H␈↓below,␈α
but␈α
the␈αessential␈α
character␈α
of␈αthe␈α
domain␈α
is␈α
that␈αit␈α
represents␈α
two␈αkinds␈α
of␈α
objects:␈αthe␈α
␈↓↓literal
␈↓ ↓H␈↓↓atoms␈↓ and the integers. The elements of ␈↓<atom>␈↓ are called ␈↓↓atoms␈↓.
␈↓ ↓H␈↓<atom>␈↓ β(:: = <literal atom> | <numeral> | -<numeral>
␈↓ ↓H␈↓<literal atom>␈↓ β(:: = <atom letter> | <literal atom><atom letter> | <literal atom><digit>
␈↓ ↓H␈↓<numeral>␈↓ β(:: = <digit> | <numeral><digit>
␈↓ ↓H␈↓<atom letter>␈↓ β(:: =␈↓α A | B | C ... | Z␈↓ ␈↓π 3␈↓
␈↓ ↓H␈↓<digit>␈↓ β(:: = ␈↓α0 | 1 | 2 ... | 9␈↓
␈↓ ↓H␈↓A␈α<literal␈α
atom>␈αis␈α
therefore␈αa␈α
string␈αof␈αuppercase␈α
letters␈αand␈α
digits,␈αsubject␈α
to␈αthe␈α
provision␈αthat
␈↓ ↓H␈↓the ␈↓↓first␈↓ character in the atom be a letter.
␈↓ ↓H␈↓For example:␈↓ βxatoms␈↓ ¬hnon atoms
␈↓ ↓H␈↓␈↓α␈↓ βxABC123␈↓ ¬h2a
␈↓ ↓H␈↓α␈↓ βx12␈↓ ¬ha
␈↓ ↓H␈↓α␈↓ βxA4D6␈↓ ¬h$$g
␈↓ ↓H␈↓α␈↓ βxNIL␈↓ ¬hABD.
␈↓ ↓H␈↓α␈↓ βxT␈↓ ¬h(A . B)
␈↓ ↓H␈↓The␈α∞characteristics␈α∞of␈α∞atoms␈α
which␈α∞most␈α∞interest␈α∞us␈α∞are␈α
their␈α∞distinguishability:␈α∞the␈α∞atom␈α∞␈↓αABC␈↓␈α
is
␈↓ ↓H␈↓distinguishable␈α∞from␈α∞the␈α∞atom␈α
␈↓αAB␈↓.␈α∞That␈α∞␈↓α"AB"␈↓␈α∞is␈α
a␈α∞part␈α∞of␈α∞␈↓α"ABC"␈↓␈α
is␈α∞not␈α∞germane␈α∞to␈α∞our␈α
current
␈↓ ↓H␈↓discussion␈↓π 4␈↓.␈α∩ Similarly,␈α∩we␈α∩will␈α∩seldom␈α∩need␈α∩to␈α∩exploit␈α∩numerical␈α∩relationships␈α∩underlying␈α∩the
␈↓ ↓H␈↓numerals;␈α
at␈α∞most␈α
we␈α
will␈α∞use␈α
simple␈α
counting␈α∞properties.␈α
Therefore␈α
most␈α∞of␈α
our␈α∞discussions␈α
will
␈↓ ↓H␈↓deal␈α∃with␈α∃non-numeric␈α∃atoms.␈α∃ Most␈α∃implementations␈α∃of␈α∃LISP␈α∃do␈α∃however␈α∃contain␈α⊗a␈α∃large
␈↓ ↓H␈↓arithmetic␈αentourage.␈α Many␈αimplementations␈αalso␈αgive␈α
a␈αwider␈αclass␈αof␈αliteral␈αatoms,␈αallowing␈α
some
␈↓ ↓H␈↓special characters to appear; for most of our discussion the above class is quite sufficient.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 3␈↓ We use ellipses here as a convienient abbreviation.
␈↓ ↓H␈↓␈↓π 4␈↓ However, we will discuss such topics in Section 7.3 on string processing.
␈↓ ↓H␈↓␈↓↓6 Symbolic expressions␈↓ 71.2␈↓
␈↓ ↓H␈↓The␈α⊃domain␈α⊃of␈α⊃Symbolic␈α⊃expressions,␈α⊃called␈α⊂␈↓<sexpr>␈↓␈α⊃is␈α⊃defined␈α⊃inductively␈α⊃over␈α⊃the␈α⊂domain
␈↓ ↓H␈↓␈↓<atom>␈↓␈↓π 5␈↓.
␈↓ ↓H␈↓␈↓ β8␈↓↓1.␈↓ Any element of ␈↓<atom>␈↓ is an element of ␈↓<sexpr>␈↓.
␈↓ ↓H␈↓␈↓ β8␈↓↓2.␈↓␈α∂If␈α⊂␈↓λα␈↓β1␈↓␈α∂and␈α⊂␈↓λα␈↓β2␈↓␈α∂are␈α⊂elements␈α∂of␈α∂␈↓<sexpr>␈↓,␈α⊂then␈α∂the␈α⊂␈↓↓dotted-pair␈↓␈α∂␈↓α(␈↓λα␈↓β1␈↓α.␈↓λα␈↓β2␈↓α)␈↓␈α⊂is␈α∂in
␈↓ ↓H␈↓␈↓ β8␈↓<sexpr>␈↓.
␈↓ ↓H␈↓Thus␈α␈↓<sexpr>␈↓␈αincludes␈α␈↓<atom>␈↓␈αas␈αa␈αproper␈αsubset.␈αThe␈αnotation␈αwe␈αchose␈αfor␈αthe␈αdotted-pairs␈αis
␈↓ ↓H␈↓the following:
␈↓ ↓H␈↓A␈α
dotted-pair␈αconsists␈α
of␈α
a␈αleft-parenthesis␈α
followed␈α
by␈αan␈α
S-expr,␈α
followed␈αby␈α
a␈α
period,␈αfollowed␈α
by
␈↓ ↓H␈↓␈↓ αhan S-expr, followed by a right-parenthesis.
␈↓ ↓H␈↓For example, let ␈↓λα␈↓β1␈↓ be ␈↓α(A . B)␈↓ and ␈↓λα␈↓β2␈↓ be ␈↓α(1 . T)␈↓; then ␈↓α(␈↓λα␈↓β1␈↓ . ␈↓λα␈↓β2␈↓) is ␈↓α((A . B) . (1 . T))␈↓.
␈↓ ↓H␈↓Greek␈αletters␈α␈↓λα␈↓␈αand␈α␈↓λβ␈↓␈αwill␈αbe␈αused␈αin␈αthe␈αtext␈αto␈αdesignate␈αpattern␈αmatches.␈αIn␈αthe␈αcurrent␈αcontext
␈↓ ↓H␈↓the␈α
pattern␈α
matches␈α
will␈α
involve␈α
S-expressions;␈αthey␈α
can␈α
match␈α
any␈α
well-formed␈α
S-expression.␈α For␈α
a
␈↓ ↓H␈↓further␈α
example,␈αlet␈α
␈↓α(A . (B . C))␈↓␈αbe␈α
␈↓α(␈↓λα␈↓α . ␈↓λβ␈↓α)␈↓␈α
then␈α␈↓λα␈↓␈α
is␈α␈↓αA␈↓␈α
and␈α
␈↓λβ␈↓␈αis␈α
␈↓α(B . C)␈↓.␈α These␈α
variables␈αare␈α
called
␈↓ ↓H␈↓␈↓↓match-variables␈↓ or ␈↓↓meta-variables␈↓.
␈↓ ↓H␈↓Finally here's a BNF description of the full set of S-expressions.
␈↓ ↓H␈↓␈↓ ∧E<sexpr> :: = <atom> | ␈↓α(␈↓<sexpr> . <sexpr>␈↓α)
␈↓ ↓H␈↓Notice␈α∞that␈α∞if␈α
we␈α∞allow␈α∞real␈α
numbers␈α∞as␈α∞atoms␈α∞then␈α
some␈α∞care␈α∞would␈α
need␈α∞to␈α∞be␈α∞exercised␈α
when
␈↓ ↓H␈↓writing␈αS-expressions.␈αFor␈αexample,␈αshould␈α␈↓α(3.1.2)␈↓␈αbe␈αinterpreted␈αas␈αthe␈αdotted␈αpair␈α␈↓α(3␈α.␈α1.2)␈↓,␈αas␈αthe
␈↓ ↓H␈↓dotted␈α⊃pair␈α∩␈↓α(3.1 . 2)␈↓,␈α⊃or␈α∩is␈α⊃it␈α∩just␈α⊃an␈α∩ill-formed␈α⊃expression?␈α∩ Interpretation␈α⊃of␈α∩such␈α⊃ambiguous
␈↓ ↓H␈↓constructs will depend on the implementation; such details are discussed later.
␈↓ ↓H␈↓Examples:␈↓ βxS-exprs␈↓ ε8non S-exprs
␈↓ ↓H␈↓α␈↓ βxA␈↓ ε8A . B
␈↓ ↓H␈↓α␈↓ βx(A . B)␈↓ ε8(A . B . C)
␈↓ ↓H␈↓α␈↓ βx(((A . B) . C) . (A . B))␈↓ ε8((A . B))
␈↓ ↓H␈↓Recall␈αour␈αcaveat␈αon␈α
numerals␈αand␈αnumbers;␈αit␈α
also␈αapplies␈αhere.␈αThe␈α
set␈αdescribed␈αby␈α<sexpr>␈αis␈α
a
␈↓ ↓H␈↓␈↓↓specific␈↓␈α⊂syntactic␈α⊂representation␈α⊂of␈α⊃the␈α⊂domain␈α⊂␈↓<sexpr>␈↓.␈α⊂ However,␈α⊃the␈α⊂set␈α⊂<sexpr>␈α⊂will␈α⊃be␈α⊂a
␈↓ ↓H␈↓convenient␈α∩notation␈α∩since␈α∩it␈α∩makes␈α∩explicit␈α∪the␈α∩construction␈α∩of␈α∩the␈α∩composite␈α∩S-expr␈α∪from␈α∩its
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 5␈↓ We will not give the termination clause, but it is assumed to hold.
␈↓ ↓H␈↓␈↓↓1.2␈↓ ε⊂Symbolic Expressions: Abstract Data Structures 7␈↓
␈↓ ↓H␈↓components␈↓π 6␈↓, and the notation is also consistent with LISP history.
␈↓ ↓H␈↓However␈α⊂there␈α⊂is␈α⊂more␈α⊂to␈α⊂the␈α⊂domain␈α⊂␈↓<sexpr>␈↓␈α⊂than␈α⊂syntax,␈α⊂just␈α⊂as␈α⊂there␈α⊂is␈α⊂more␈α⊂to␈α⊂␈↓N␈↓␈α⊂than
␈↓ ↓H␈↓positional␈α∞notation␈↓π 7␈↓.␈α∞ What␈α∂␈↓↓are␈↓␈α∞the␈α∞essential␈α∞features␈α∂of␈α∞S-expressions?␈α∞Symbolic␈α∂expressions␈α∞are
␈↓ ↓H␈↓either␈α
atomic␈α
or␈α
they␈α
have␈α
two␈α∞components.␈α
If␈α
we␈α
are␈α
confronted␈α
with␈α
a␈α∞non-atomic␈α
S-expression
␈↓ ↓H␈↓then␈αwe␈αwant␈αa␈αmeans␈αof␈αdistinguishing␈αbetween␈αthe␈α"first"␈αand␈αthe␈α"second"␈αcomponent.␈αThe␈α"dot
␈↓ ↓H␈↓notation"␈αdoes␈α
this␈αfor␈α
us,␈αbut␈α
obviously␈α"(",␈α
")",␈αand␈α
"."␈αof␈α
the␈αdotted-pairs␈α
are␈αsimply␈α
notation␈αor
␈↓ ↓H␈↓syntax.␈α∂ We␈α∂could␈α∞have␈α∂just␈α∂as␈α∞well␈α∂represented␈α∂the␈α∞dotted-pair␈α∂of␈α∂␈↓αA␈↓␈α∞and␈α∂␈↓αB␈↓␈α∂as␈α∂the␈α∞set-theoretic
␈↓ ↓H␈↓ordered pair, ␈↓α<A,B>␈↓ or any other notation which preserves the essentials of the domain ␈↓<sexpr>␈↓.
␈↓ ↓H␈↓The␈α⊃distinctions␈α⊃between␈α∩abstract␈α⊃objects␈α⊃and␈α⊃their␈α∩representation␈α⊃are␈α⊃quite␈α⊃important.␈α∩As␈α⊃we
␈↓ ↓H␈↓continue␈αour␈αstudy␈αof␈αmore␈αand␈αmore␈αcomplex␈αdata␈αstructures␈αthe␈αuse␈αof␈αan␈αabstract␈αdata␈αstructure
␈↓ ↓H␈↓instead␈α∞of␈α
one␈α∞of␈α
its␈α∞representations␈α
can␈α∞mean␈α
the␈α∞difference␈α
between␈α∞a␈α
clear␈α∞and␈α∞clean␈α
program
␈↓ ↓H␈↓and␈α∀a␈α∀confusing␈α∀and␈α∀complicated␈α∀program.␈α∀There␈α∀are␈α∀similar␈α∀gains␈α∀for␈α∀us␈α∀when␈α∃we␈α∀study
␈↓ ↓H␈↓algorithms␈α⊂defined␈α∂over␈α⊂these␈α∂abstract␈α⊂data␈α∂structures.␈α⊂The␈α∂less␈α⊂the␈α∂algorithm␈α⊂knows␈α⊂about␈α∂the
␈↓ ↓H␈↓representation␈α
of␈α
the␈α∞data␈α
structure,␈α
the␈α
easier␈α∞it␈α
will␈α
be␈α
to␈α∞modify␈α
or␈α
understand␈α∞that␈α
algorithm.
␈↓ ↓H␈↓Indeed␈αyou␈αmay␈αhave␈αalready␈αexperienced␈αthis␈αphenomenon␈αif␈αyou␈αhave␈αprogrammed.␈α A␈αprogram
␈↓ ↓H␈↓written␈α
in␈α
a␈α
high-level␈α
language␈α
is␈αalmost␈α
always␈α
more␈α
understandable␈α
than␈α
its␈αmachine-language
␈↓ ↓H␈↓counterpart.␈α⊃ The␈α⊃high-level␈α⊃program␈α⊃is␈α⊃more␈α⊃abstract␈α⊃whereas␈α⊃the␈α∩machine-language␈α⊃program
␈↓ ↓H␈↓knows␈α∞a␈α∞great␈α∞deal␈α∞about␈α∞representations.␈α∞ Finally,␈α
if␈α∞you␈α∞still␈α∞doubt␈α∞that␈α∞representations␈α∞make␈α
a
␈↓ ↓H␈↓difference␈α
in␈α∞clarity,␈α
try␈α
doing␈α∞long␈α
division␈α
in␈α∞Roman␈α
numerals.␈α
We␈α∞will␈α
say␈α
much␈α∞more␈α
about
␈↓ ↓H␈↓abstraction and representation in algorithms and data structures as we proceed.
␈↓ ↓H␈↓␈↓ βt␈↓↓1.3 Trees: Representations of Symbolic expressions␈↓
␈↓ ↓H␈↓Besides␈α_the␈α_more␈α_conventional␈α_typographical␈α_notations,␈α_S-expressions␈α_also␈α_have␈α↔interesting
␈↓ ↓H␈↓␈↓↓graphical␈↓␈α∂representations.␈α∂ S-exprs␈α∂have␈α∂a␈α∂natural␈α∂interpretation␈α∂as␈α∂a␈α∂structure␈α∂which␈α∂we␈α∂call␈α∞a
␈↓ ↓H␈↓LISP-tree or L-tree.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 6␈↓␈α∂Just␈α∂as␈α∂the␈α∞"successor"␈α∂notation␈α∂shows␈α∂the␈α∞construction␈α∂of␈α∂the␈α∂numbers␈α∞from␈α∂␈↓α0␈↓.␈α∂This␈α∂kind␈α∞of
␈↓ ↓H␈↓notation␈α
will␈αbe␈α
much␈αmore␈α
useful␈α
in␈αLISP,␈α
since␈αour␈α
interest␈α
in␈αdata␈α
structures␈αwill␈α
focus␈α
on␈αthe
␈↓ ↓H␈↓construction process and the interrelationships between components of an S-expr.
␈↓ ↓H␈↓␈↓π 7␈↓␈α␈↓α2␈↓,␈α
II␈αin␈αRoman␈α
numerals,␈α10␈αin␈α
binary,␈α"zwei"␈αin␈α
German␈α...␈αare␈α
all␈αrepresentations␈αof␈α
the␈αsame
␈↓ ↓H␈↓number.
␈↓ ↓H␈↓␈↓↓8 Symbolic expressions␈↓ 71.3␈↓
␈↓ ↓H␈↓Here are some L-trees:
␈↓"␈↓ ↓H␈↓∂ /\ /\
␈↓"␈↓ ↓H␈↓∂ / \ / \
␈↓"␈↓ ↓H␈↓∂ / \ / /\
␈↓"␈↓ ↓H␈↓∂ /\ /\ / / \
␈↓"␈↓ ↓H␈↓∂ / \ / \ ␈↓αA␈↓∂ ␈↓αB␈↓∂ ␈↓αNIL␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓α1␈↓∂ ␈↓α2␈↓∂ ␈↓αA␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂ ␈↓αD␈↓∂ ␈↓αE␈↓∂
␈↓ ↓H␈↓We can give an inductive definition:
␈↓ ↓H␈↓␈↓ β8␈↓↓1.␈↓ Any element of <atom> is an L-tree.
␈↓ ↓H␈↓␈↓ β8␈↓↓2.␈↓ If ␈↓αn␈↓β1␈↓ and ␈↓αn␈↓β2␈↓ are L-trees then
␈↓"␈↓ ↓H␈↓∂␈↓ β8 /\
␈↓"␈↓ ↓H␈↓∂␈↓ β8 / \
␈↓"␈↓ ↓H␈↓∂␈↓ β8 / \
␈↓"␈↓ ↓H␈↓∂␈↓ β8 ␈↓αn␈↓β1␈↓∂ ␈↓αn␈↓β2␈↓∂
␈↓ ↓H␈↓␈↓ β8also forms an L-tree.
␈↓ ↓H␈↓Most␈α
important:␈αthere␈α
are␈α
no␈αintersecting␈α
branches.␈α
Later␈αwe␈α
will␈α
talk␈αabout␈α
more␈αgeneral␈α
structures
␈↓ ↓H␈↓called list-structures.
␈↓ ↓H␈↓You␈αcan␈αsee␈αhow␈αto␈αinterpret␈αS-exprs␈αas␈αL-trees.␈α The␈αatoms␈αare␈αinterpreted␈αas␈αterminal␈αnodes;␈αand
␈↓ ↓H␈↓since␈αnon-atomic␈αS-exprs␈αalways␈αhave␈αtwo␈αsub-expressions␈αwe␈αcan␈αwrite␈αthe␈αfirst␈αsub-expression␈αas
␈↓ ↓H␈↓the left branch of an L-tree and the second sub-expression as the right branch.
␈↓ ↓H␈↓For example:
␈↓"␈↓ ↓H␈↓∂ ␈↓α(A . B)␈↓∂␈↓ ¬_␈↓α(A . (B . C))␈↓∂␈↓ λ(␈↓α((A . B) . C)␈↓∂
␈↓"␈↓ ↓H␈↓∂ /\␈↓ ¬_ /\␈↓ λ( /\
␈↓"␈↓ ↓H␈↓∂ / \␈↓ ¬_ / \␈↓ λ( / \
␈↓"␈↓ ↓H␈↓∂ ␈↓αA␈↓∂ ␈↓αB␈↓∂␈↓ ¬_ / /\␈↓ λ( /\ \
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_ / / \␈↓ λ( / \ \
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_ ␈↓αA␈↓∂ ␈↓αB␈↓∂ ␈↓αC␈↓∂␈↓ λ( ␈↓αA␈↓∂ ␈↓αB␈↓∂ ␈↓αC␈↓∂
␈↓ ↓H␈↓Other representations of LISP-trees are possible; for example ␈↓α(A . (B . C))␈↓ can be expressed as: ␈↓α
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
ααααα→~ # ~ #αβααααααααααα→~ # ~ # ~
␈↓"␈↓ ↓H␈↓
%αβα∀ααα$ %αβα∀αβα$
␈↓"␈↓ ↓H␈↓
↓ ↓ ↓
␈↓"␈↓ ↓H␈↓
␈↓αA␈↓
␈↓αB␈↓
␈↓αC␈↓
␈↓ ↓H␈↓␈↓↓1.3␈↓ ε∃Trees: Representations of Symbolic expressions 9␈↓
␈↓ ↓H␈↓α␈↓or:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
ααααα→~ A ~ #αβααααααααααα→~ B ~ C ~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$
␈↓ ↓H␈↓These last two representations are called ␈↓↓box-notation␈↓.
␈↓ ↓H␈↓Please␈α∂keep␈α∂in␈α∞mind␈α∂the␈α∂distinction␈α∞between␈α∂the␈α∂abstract␈α∞S-expr␈α∂and␈α∂the␈α∂several␈α∞representations
␈↓ ↓H␈↓which we have shown.
␈↓ ↓H␈↓The␈α⊂question␈α⊂of␈α⊂representation␈α⊃is␈α⊂so␈α⊂important␈α⊂and␈α⊂will␈α⊃occur␈α⊂so␈α⊂frequently␈α⊂that␈α⊃we␈α⊂introduce
␈↓ ↓H␈↓notation␈αfor␈αa␈αrepresentational␈αmapping,␈α␈↓λr␈↓.␈α To␈αrepresent␈αdomain␈α␈↓D␈↓␈αin␈αdomain␈α␈↓E␈↓,␈αwe␈αwill␈αdefine␈α
a
␈↓ ↓H␈↓function ␈↓λr␈↓βD→E␈↓ which usually will be specified inductively, and will express the desired mapping.
␈↓ ↓H␈↓For example a representational mapping ␈↓λr␈↓β<sexpr>→L-tree␈↓ can be given:
␈↓ ↓H␈↓␈↓ ¬:␈↓λr␈↓∞(␈↓<atom>␈↓∞)␈↓ = <atom>
␈↓ ↓H␈↓␈↓ ¬_and for ␈↓λα␈↓ and ␈↓λβ␈↓ in <sexpr>:
␈↓"␈↓ ↓H␈↓∂␈↓ ∧H␈↓λr␈↓∞(␈↓α(␈↓λα␈↓α . ␈↓λβ␈↓α)␈↓∞)␈↓ =␈↓∂␈↓ ελ /\
␈↓"␈↓ ↓H␈↓∂␈↓ ∧H␈↓ ελ / \
␈↓"␈↓ ↓H␈↓∂␈↓ ∧H␈↓ ελ / \
␈↓"␈↓ ↓H␈↓∂␈↓ ∧H␈↓ ελ␈↓λr␈↓∞(␈↓λα␈↓∞)␈↓∂ ␈↓λr␈↓∞(␈↓λβ␈↓∞)␈↓∂
␈↓ ↓H␈↓Typically context will determine the appropriate subscript on the ␈↓λr␈↓-mapping; thus we will omit it.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I Which of the following are dotted-pairs?
␈↓ ↓H␈↓␈↓ αX␈↓↓1.␈↓α (X . Y) ␈↓↓2.␈↓α ((A . (B . C)) ␈↓↓3.␈↓α A2 ␈↓↓4.␈↓α (X . Y2 . Z)
␈↓ ↓H␈↓II Write the following as LISP trees:
␈↓ ↓H␈↓␈↓ αX␈↓↓1.␈↓α ((A . B) . (B . (C . D))) ␈↓↓2.␈↓α (((A . B) . C) . E)
␈↓ ↓H␈↓α␈↓ αX␈↓↓3.␈↓α ((X . NIL) . (Y . (Z . NIL))) ␈↓↓4.␈↓α (NIL . NIL)
␈↓ ↓H␈↓␈↓↓10 Symbolic expressions␈↓ 71.3␈↓
␈↓ ↓H␈↓III Write the following LISP trees as S-exprs:
␈↓"␈↓ ↓H␈↓∂ ␈↓↓1.␈↓∂␈↓ βx ␈↓↓2.␈↓∂␈↓ ε8 ␈↓↓3.␈↓∂
␈↓"␈↓ ↓H␈↓∂ /\␈↓ βx /\␈↓ ε8 /\
␈↓"␈↓ ↓H␈↓∂ / \␈↓ βx / \␈↓ ε8 / \
␈↓"␈↓ ↓H␈↓∂ / /\␈↓ βx ␈↓αA␈↓∂ /\␈↓ ε8 ␈↓αA␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂ / / \␈↓ βx / \␈↓ ε8 / \
␈↓"␈↓ ↓H␈↓∂ ␈↓αA␈↓∂ ␈↓αB␈↓∂ ␈↓αC␈↓∂␈↓ βx / \␈↓ ε8 ␈↓αB␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂␈↓ βx /\ /\␈↓ ε8 / \
␈↓"␈↓ ↓H␈↓∂␈↓ βx / \ ␈↓αD␈↓∂ ␈↓αE␈↓∂␈↓ ε8 ␈↓αC␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂␈↓ βx ␈↓αA␈↓∂ ␈↓αNIL␈↓∂␈↓ ε8 / \
␈↓"␈↓ ↓H␈↓∂␈↓ βx␈↓ ε8 ␈↓αD␈↓∂ ␈↓αNIL␈↓∂
␈↓"␈↓ ↓H␈↓
␈↓4.␈↓
␈↓5.␈↓
␈↓"␈↓ ↓H␈↓
⊂αααααπααα⊃ ⊂αααπααααα⊃ ⊂ααααααπααα⊃ ⊂αααπααα⊃ ⊂αααπααααα⊃
␈↓"␈↓ ↓H␈↓
~ # ~ #αβα→~ # ~ # ~ ~ CONS ~ #αβα→~ X ~ #αβα→~ Y ~ NIL ~
␈↓"␈↓ ↓H␈↓
%ααβαα∀ααα$ %αβα∀ααβαα$ %αααααα∀ααα$ %ααα∀ααα$ %ααα∀ααααα$
␈↓"␈↓ ↓H␈↓
↓ ~ ↓
␈↓"␈↓ ↓H␈↓
CAR ~ NIL
␈↓"␈↓ ↓H␈↓
~ ⊂αααααπααα⊃ ⊂αααπααααα⊃
␈↓"␈↓ ↓H␈↓
%α→~ # ~ #αβα→~ # ~ # ~
␈↓"␈↓ ↓H␈↓
%ααβαα∀ααα$ %αβα∀ααβαα$
␈↓"␈↓ ↓H␈↓
↓ ↓ ↓
␈↓"␈↓ ↓H␈↓
QUOTE A NIL
␈↓ ↓H␈↓␈↓ ¬,␈↓↓1.4 Primitive Functions␈↓
␈↓ ↓H␈↓So␈αfar␈αwe␈αhave␈αdescribed␈αthe␈αdomain␈αof␈αabstract␈αobjects␈αcalled␈αS-exprs␈αand␈αhave␈αexhibited␈αseveral
␈↓ ↓H␈↓representations␈α∀for␈α∪these␈α∀objects.␈α∀ We␈α∪will␈α∀now␈α∪describe␈α∀some␈α∀functions␈α∪or␈α∀operations␈α∀to␈α∪be
␈↓ ↓H␈↓performed␈αon␈αthis␈αdomain.␈α We␈αneed␈αto␈αbe␈αa␈αbit␈α
careful␈αhere.␈αWe␈αare␈αabout␈αto␈αsee␈αone␈αof␈αthe␈α
main
␈↓ ↓H␈↓differences␈α∃between␈α∃mathematics␈α∃and␈α∃computer␈α∃science:␈α∃mathematics␈α∃emphasizes␈α∃the␈α⊗idea␈α∃of
␈↓ ↓H␈↓function; computer science emphasizes the idea of algorithm, process, or procedure.
␈↓ ↓H␈↓What␈α⊃is␈α⊃a␈α⊃function?␈α⊃Mathematically␈α⊃a␈α⊃function␈α⊃is␈α⊃simply␈α⊃a␈α⊃mapping␈α⊃such␈α⊃that␈α⊃for␈α⊃any␈α⊂given
␈↓ ↓H␈↓argument␈αin␈α
the␈αdomain␈α
of␈αthe␈α
function␈αthere␈αexists␈α
a␈αunique␈α
corresponding␈αvalue.␈α
In␈αelementary
␈↓ ↓H␈↓set␈α_theory,␈α_a␈α_definition␈α_of␈α_function␈α_␈↓αf␈↓␈α_involves␈α↔saying␈α_that␈α_␈↓αf␈↓␈α_is␈α_a␈α_set␈α_of␈α_ordered␈α↔pairs
␈↓ ↓H␈↓␈↓αf = { <x␈↓β1␈↓α, y␈↓β1␈↓α>, ...}␈↓;␈α∂the␈α∂␈↓αx␈↓βi␈↓'s␈α∂are␈α∂all␈α∂distinct␈α∂and␈α∂the␈α∂value␈α∂of␈α∂the␈α∂function␈α∂␈↓αf␈↓␈α∂for␈α∂an␈α∂argument␈α∂␈↓αx␈↓βi␈↓␈α∂is
␈↓ ↓H␈↓defined␈αto␈αbe␈αthe␈αcorresponding␈α␈↓αy␈↓βi␈↓.␈α No␈αrule␈αof␈αcomputation␈αis␈αgiven␈αto␈αlocate␈αvalues;␈αwith␈αthe␈αfirst
␈↓ ↓H␈↓definition␈αit␈α
is␈αimplicit␈α
that␈αthe␈α
internal␈αstructure␈α
of␈αthe␈α
mapping␈αdoesn't␈α
matter;␈αin␈αthe␈α
set-theoretic
␈↓ ↓H␈↓definition, the correspondence is explicitly given.
␈↓ ↓H␈↓␈↓↓1.4␈↓ λyPrimitive Functions 11␈↓
␈↓ ↓H␈↓An␈α
algorithm␈αor␈α
procedure␈αis␈α
a␈α
process␈αfor␈α
computing␈αvalues␈α
for␈α
a␈αfunction.␈α
The␈αfactorial␈α
function,
␈↓ ↓H␈↓␈↓αn!␈↓, can be computed by many different algorithms; but as a function it is a set
␈↓ ↓H␈↓␈↓ ∧Y␈↓α{<0,1>, <1,1>, <2,2>, <3,6>, ...<n,n!>, ...}␈↓.
␈↓ ↓H␈↓The␈α␈↓↓domain␈↓␈αof␈αa␈αfunction␈αis␈αthe␈αset␈αof␈αall␈αvalues␈αfor␈αwhich␈αthe␈αfunction␈αis␈αdefined;␈αthe␈α␈↓↓range␈↓␈αof␈αa
␈↓ ↓H␈↓function␈α∞is␈α∞the␈α∞set␈α∞of␈α
all␈α∞values␈α∞which␈α∞the␈α∞function␈α∞takes␈α
on.␈α∞ A␈α∞careful␈α∞definition␈α∞of␈α∞a␈α
function
␈↓ ↓H␈↓requires␈α∞specification␈α∞of␈α∞a␈α∞further␈α∞set␈α∞called␈α∞the␈α∞␈↓↓domain␈α∞of␈α∞discourse␈↓.␈α∞The␈α∞domain␈α∂of␈α∞discourse,
␈↓ ↓H␈↓named␈α∞␈↓ D␈↓,␈α∞consists␈α∞of␈α∞all␈α∞possible␈α∞values␈α∞which␈α
may␈α∞occur␈α∞as␈α∞the␈α∞argument␈α∞to␈α∞a␈α∞function.␈α∞ If␈α
the
␈↓ ↓H␈↓domain␈α
of␈α
a␈αparticular␈α
function␈α
␈↓αf␈↓␈αcoincides␈α
with␈α
␈↓ D␈↓␈αthen␈α
␈↓αf␈↓␈α
is␈α
said␈αto␈α
be␈α
a␈α␈↓↓total␈α
function␈↓␈α
(over␈α␈↓ D␈↓);␈α
if
␈↓ ↓H␈↓there␈αare␈αelements␈αof␈α␈↓ D␈↓␈αwhich␈αare␈α
not␈αin␈αthe␈αdomain␈αof␈α␈↓αf␈↓␈αthen␈α
␈↓αf␈↓␈αis␈αa␈αpartial␈αfunction,␈αand␈α␈↓αf␈↓␈αis␈α
said
␈↓ ↓H␈↓to␈αbe␈αundefined␈αfor␈α
those␈αvalues.␈α For␈αexample,␈αthe␈α
factorial␈αfunction␈αis␈αtypically␈αconsidered␈α
to␈αbe
␈↓ ↓H␈↓partial␈αover␈αthe␈αintegers:␈αtotal␈αfor␈αthe␈αnatural␈αnumbers,␈αbut␈αundefined␈αfor␈αnegative␈αintegers.␈α Thus
␈↓ ↓H␈↓the␈α∩concept␈α⊃of␈α∩"total"␈α⊃or␈α∩"partial"␈α⊃is␈α∩relative␈α⊃to␈α∩a␈α⊃specified␈α∩domain␈α⊃of␈α∩discourse.␈α∩ However,␈α⊃a
␈↓ ↓H␈↓function␈α␈↓αf␈↓␈αtotal␈αover␈αa␈αdomain␈α␈↓ D␈↓β1␈↓␈αcan␈αbe␈αextended␈αto␈αbe␈αtotal␈αover␈αa␈αdomain␈α␈↓ D␈↓β1␈↓∪␈↓ D␈↓β2␈↓␈αby␈αassigning
␈↓ ↓H␈↓values␈α
to␈α␈↓αf(d)␈↓␈α
for␈α␈↓αd␈↓λε␈↓ D␈↓β2␈↓-␈↓ D␈↓β1␈↓.␈α
In␈αthis␈α
way,␈αfactorial␈α
can␈αbe␈α
extended␈αto␈α
be␈αtotal␈α
over␈αthe␈α
integers␈αby
␈↓ ↓H␈↓defining␈α␈↓αn!␈↓␈αto␈αbe␈α␈↓α0␈↓␈α
for␈α␈↓αn␈↓␈αless␈αthan␈α␈↓α0␈↓.␈α
We␈αmay␈αextend␈αthe␈αrange␈α
of␈αa␈αfunction␈αwhen␈αwe␈αextend␈α
the
␈↓ ↓H␈↓domain;␈α
thus␈α
␈↓αf(d)␈↓␈α
need␈α
not␈α
be␈α
in␈α
the␈α
range␈α
of␈α
the␈α
original␈α
␈↓αf␈↓.␈α
For␈α
example,␈α
we␈α
added␈α
␈↓α0␈↓␈α
to␈αthe␈α
range
␈↓ ↓H␈↓when␈α∪we␈α∪extended␈α∩the␈α∪factorial␈α∪function.␈α∪When␈α∩we␈α∪extend␈α∪the␈α∩range␈α∪we␈α∪must␈α∪specify␈α∩what
␈↓ ↓H␈↓additions have been made.
␈↓ ↓H␈↓A␈α
substantive␈αdecision␈α
needs␈α
to␈αbe␈α
made␈α
on␈αhow␈α
we␈α
are␈αto␈α
handle␈α
partial␈αfunctions␈↓π 8␈↓.␈α
Since␈αwe␈α
are
␈↓ ↓H␈↓attempting␈α
to␈α
be␈α
reasonably␈αrealistic␈α
about␈α
our␈α
modelling␈α
of␈αcomputation␈α
we␈α
should␈α
be␈α
as␈αprecise␈α
as
␈↓ ↓H␈↓possible␈α∞in␈α∂our␈α∞formalism.␈α∂ We␈α∞could␈α∂introduce␈α∞a␈α∞class␈α∂of␈α∞error␈α∂values␈α∞and␈α∂include␈α∞them␈α∂in␈α∞the
␈↓ ↓H␈↓range␈α⊂of␈α∂␈↓αf␈↓;␈α⊂these␈α∂values␈α⊂would␈α⊂be␈α∂given␈α⊂as␈α∂the␈α⊂result␈α∂of␈α⊂applying␈α⊂␈↓αf␈↓␈α∂to␈α⊂an␈α∂argument␈α⊂not␈α⊂in␈α∂its
␈↓ ↓H␈↓domain;␈α
or␈α
we␈α
could␈αsimply␈α
say␈α
that␈α
the␈αresult␈α
is␈α
"unspecified"␈α
␈↓π 9␈↓.␈α We␈α
shall␈α
pick␈α
an␈αintermediate
␈↓ ↓H␈↓position;␈αwe␈α
shall␈αintroduce␈α␈↓↓one␈↓␈α
new␈αelement,␈α
␈↓λB␈↓,␈αcalled␈α"unspecified"␈α
or␈α"undefined",␈αor␈α
"bottom"␈↓π 10␈↓.
␈↓ ↓H␈↓We␈α∞will␈α∞define␈α∞all␈α∞our␈α∞functions␈α∞over␈α∞domains␈α∞augmented␈α∞with␈α∞this␈α∞element;␈α∞thus␈α∞constructs␈α
like
␈↓ ↓H␈↓␈↓αf(␈↓λB␈↓α) = a␈↓␈α⊂are␈α∂allowed.␈α⊂For␈α∂the␈α⊂moment,␈α∂think␈α⊂of␈α∂␈↓λB␈↓␈α⊂as␈α∂covering␈α⊂all␈α∂anomalous␈α⊂conditions␈α∂which
␈↓ ↓H␈↓could be detected and printed as error messages; later we will refine this interpretation.
␈↓ ↓H␈↓As␈α∩we␈α∩define␈α∩new␈α∪data␈α∩structures␈α∩we␈α∩will␈α∩frequently␈α∪want␈α∩to␈α∩extend␈α∩our␈α∩functions␈α∪to␈α∩larger
␈↓ ↓H␈↓domains.␈α∂For␈α∂most␈α∂of␈α∂our␈α∂purposes,␈α∂a␈α∂function␈α∂␈↓αf␈↓␈α∂defined␈α∂on␈α∂(an␈α∂augmented␈α∂domain)␈α∂␈↓ D␈↓␈α∂will␈α∂be
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 8␈↓␈α
Partial␈α
functions␈α∞occur␈α
naturally␈α
in␈α∞computation.␈α
Most␈α
programs␈α
will␈α∞fail␈α
to␈α
give␈α∞results␈α
under
␈↓ ↓H␈↓some␈α∂circumstances.␈α∂The␈α∂function␈α∂which␈α∂that␈α∂program␈α∂is␈α∂computing␈α∂is␈α∂a␈α∂partial␈α⊂function.␈α∂Some
␈↓ ↓H␈↓error␈αconditions␈αcan␈αproduce␈αerror␈αmessages;␈αsome␈αerror␈αconditions␈αmay␈αcause␈αthe␈αprogram␈αto␈αloop.
␈↓ ↓H␈↓We will analyze both situations.
␈↓ ↓H␈↓␈↓π 9␈↓␈αHow␈α"unspecified"␈αmanifests␈αitself␈αon␈α
a␈αmachine␈αwill␈αdepend␈αon␈αthe␈α
implementation.␈αSometimes
␈↓ ↓H␈↓error messages are given; sometimes not.
␈↓ ↓H␈↓␈↓π 10␈↓ "bottom" is sometimes written ␈↓λW␈↓.
␈↓ ↓H␈↓␈↓↓12 Symbolic expressions␈↓ 41.4␈↓
␈↓ ↓H␈↓extended␈α
to␈α
a␈αlarger␈α
domain,␈α
␈↓ D␈↓∪␈↓ D␈↓β1␈↓,␈αby␈α
defining␈α
␈↓αf(d␈↓β1␈↓α) = f(␈↓λB␈↓α)␈↓␈αfor␈α
␈↓αd␈↓β1␈↓λε␈↓ D␈↓β1␈↓-␈↓ D␈↓␈↓π 11␈↓,␈α
therefore␈α
␈↓αf(␈↓λB␈↓α)␈↓␈αneed
␈↓ ↓H␈↓not␈α∀be␈α∀␈↓λB␈↓.␈α∀ However␈α∃many␈α∀of␈α∀the␈α∀functions␈α∀which␈α∃we␈α∀will␈α∀examine␈α∀are␈α∀defined␈α∃such␈α∀that
␈↓ ↓H␈↓␈↓αf(..., ␈↓λB␈↓α, ...) = ␈↓λB␈↓. Functions which possess this property are called ␈↓↓strict functions␈↓.
␈↓ ↓H␈↓To apply this discussion of ␈↓λB␈↓ to S-exprs we will define an extended domain ␈↓ S␈↓ to be:
␈↓ ↓H␈↓␈↓ ¬E␈↓ S␈↓ = ␈↓<sexpr>␈↓ ∪ {␈↓λB␈↓}.
␈↓ ↓H␈↓Then␈αwe␈α
can␈αtalk␈αabout␈α
functions␈αwhich␈α
are␈αtotal␈αover␈α
␈↓ S␈↓␈αor␈α
over␈α␈↓<sexpr>␈↓,␈αand␈α
we␈αwill␈αtalk␈α
about
␈↓ ↓H␈↓functions␈αwhich␈αare␈αpartial␈αover␈α␈↓<sexpr>␈↓.␈α When␈αwe␈αask␈αif␈αan␈αS-expr␈αfunction␈αis␈αpartial␈αor␈αtotal
␈↓ ↓H␈↓without␈α∂specifying␈α∂a␈α∂domain,␈α⊂we␈α∂are␈α∂asking␈α∂the␈α⊂question␈α∂over␈α∂the␈α∂natural,␈α⊂unextended␈α∂domain,
␈↓ ↓H␈↓␈↓<sexpr>␈↓.
␈↓ ↓H␈↓We␈α∞will␈α
now␈α∞move␈α∞towards␈α
a␈α∞more␈α∞algorithmic␈α
presentation.␈α∞We␈α∞will␈α
return␈α∞to␈α∞the␈α
mathematical
␈↓ ↓H␈↓aspects␈α∞occasionally,␈α∞but␈α∞our␈α∞main␈α∞concern␈α∞in␈α∂this␈α∞text␈α∞is␈α∞a␈α∞treatment␈α∞of␈α∞algorithms␈α∂expressed␈α∞in
␈↓ ↓H␈↓LISP.␈α
We␈α∞will␈α
continue␈α
to␈α∞say␈α
"LISP function"␈α
or␈α∞just␈α
"function",␈α
but␈α∞what␈α
we␈α
are␈α∞expressing␈α
or
␈↓ ↓H␈↓describing␈αis␈αa␈αparticular␈αalgorithm␈αor␈αprocedure,␈αnot␈αa␈αfunction␈αin␈αthe␈αmathematical␈αsense.␈αWhen
␈↓ ↓H␈↓we wish to stress the distinction we will use "procedure" or "algorithm".
␈↓ ↓H␈↓The␈αfirst␈αLISP␈αfunction␈αwe␈αconsider␈αis␈α␈↓αcons␈↓.␈αThis␈αbinary␈αfunction␈αis␈αused␈αto␈αgenerate␈αS-exprs␈αfrom
␈↓ ↓H␈↓less␈α
complicated␈α
S-exprs.␈α
␈↓αcons␈↓␈α
is␈α
called␈α
a␈α
␈↓↓constructor␈↓-function␈α
and␈α
is␈α
a␈α
strict␈α
function␈↓π 12␈↓;␈α
it␈α
is␈αa␈α
total
␈↓ ↓H␈↓function␈αover␈αthe␈αdomain␈α␈↓ S␈↓.␈α
More␈αprecisely,␈αsince␈α␈↓αcons␈↓␈αis␈α
a␈α␈↓↓binary␈↓␈αfunction,␈αeach␈αargument␈αof␈α
␈↓αcons␈↓
␈↓ ↓H␈↓is␈αfree␈αto␈αtake␈αon␈αvalues␈αfrom␈α␈↓ S␈↓␈↓π 13␈↓.␈α Whenever␈α␈↓αcons␈↓␈αis␈αpresented␈αwith␈αtwo␈αelements␈α␈↓λα␈↓␈αand␈α␈↓λβ␈↓␈αfrom
␈↓ ↓H␈↓␈↓<sexpr>␈↓,␈α
␈↓αcons[␈↓λα␈↓α;␈↓λβ␈↓α]␈↓␈αreturns␈α
a␈α
new␈αS-expr␈α
␈↓α(␈↓λα␈↓α . ␈↓λβ␈↓α)␈↓.␈α
Interpreted␈αas␈α
a␈α
LISP-tree,␈α␈↓αcons[␈↓λα␈↓α;␈↓λβ␈↓α]␈↓␈α
forms␈αa␈α
new
␈↓ ↓H␈↓LISP tree which has a left branch ␈↓λα␈↓ and has a right branch ␈↓λβ␈↓.
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓α␈↓ ¬Ocons[A; B] = (A . B)
␈↓ ↓H␈↓α␈↓ ¬⊃cons[(A . B); C] = ((A . B) .C)
␈↓ ↓H␈↓Expressions␈α⊃which␈α⊃can␈α⊃have␈α⊃a␈α⊃value,␈α⊃are␈α⊂called␈α⊃␈↓↓forms␈↓.␈α⊃ S-exprs␈α⊃are␈α⊃forms␈α⊃since␈α⊃they␈α⊃are␈α⊂the
␈↓ ↓H␈↓constants␈α
of␈α
our␈αlanguage:␈α
the␈α
value␈α
of␈αa␈α
constant␈α
is␈α
that␈αconstant.␈α
Function␈α
applications␈αare␈α
forms:
␈↓ ↓H␈↓the value is the result of performing the designated function on the designated arguments.
␈↓ ↓H␈↓Notice␈αthat␈αwe␈αare␈α
designating␈αfunction␈αapplication␈αin␈αLISP␈α
by␈α"function␈αname,␈αfollowed␈αby␈α
a␈αlist
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 11␈↓␈αThe␈αexception␈αto␈αthis␈αextension␈αconvention␈αinvolves␈αthe␈αdefinition␈αof␈αpredicates␈αwhich␈αcan␈αtell
␈↓ ↓H␈↓whether␈αor␈αnot␈αan␈αarbitrary␈αelement␈αis␈αin␈αa␈αspecified␈αdomain.␈αThese␈αpredicates␈αalways␈αgive␈αtrue␈αor
␈↓ ↓H␈↓false when applied to any element other than ␈↓λB␈↓.
␈↓ ↓H␈↓␈↓π 12␈↓ For an alternative interpretation of ␈↓αcons␈↓ see [Fri 76a].
␈↓ ↓H␈↓␈↓π 13␈↓ We could also say that ␈↓αcons␈↓ is total over the Cartesian product ␈↓ S␈↓x␈↓ S␈↓.
␈↓ ↓H␈↓␈↓↓1.4␈↓ λyPrimitive Functions 13␈↓
␈↓ ↓H␈↓of␈αarguments␈αdelimited␈αby␈α
`['␈αand␈α`]'␈↓π 14␈↓."␈αThe␈α
`[...]'-notation␈αis␈αpart␈αof␈α
the␈αLISP␈αsyntax␈αand␈α
we␈αwill
␈↓ ↓H␈↓reserve␈α`(...)'-notation␈αfor␈α
the␈αfunction␈αapplication␈αof␈α
mathematics.␈αIn␈αa␈α
few␈αplaces␈αin␈αour␈α
discussions
␈↓ ↓H␈↓the␈αdistinction␈αwill␈αbe␈αimportant.␈α Typically␈αthe␈αdistinctions␈αwill␈αoccur␈αwhen␈αwe␈αwish␈αto␈αdistinguish
␈↓ ↓H␈↓between the LISP algorithm and the mathematical function computed by that algorithm.
␈↓ ↓H␈↓A␈αcritical␈αdistinction␈αhas␈αalready␈αarisen␈αin␈αdiscussing␈αforms␈αlike␈α␈↓αcons[A;B]␈↓.␈αThe␈αconstructor␈α
␈↓αcons␈↓␈αis
␈↓ ↓H␈↓actually␈α
an␈α
algorithm.␈α
Since␈α
it␈αis␈α
a␈α
primitive␈α
algorithm␈α
it␈α
will␈αbe␈α
represented␈α
on␈α
a␈α
machine␈α
by␈αa
␈↓ ↓H␈↓sequence␈α∪of␈α∪operations␈α∪which␈α∩depend␈α∪on␈α∪the␈α∪implementation␈α∩of␈α∪S-exprs␈α∪and␈α∪depend␈α∪on␈α∩the
␈↓ ↓H␈↓primitive␈α
operations␈α
of␈αthe␈α
hardware␈α
machine.␈α
The␈α␈↓↓process␈↓␈α
of␈α
extracting␈αa␈α
value␈α
from␈α
the␈αform
␈↓ ↓H␈↓␈↓αcons[A; B]␈↓␈α∞is␈α∞called␈α∞␈↓↓evaluation␈↓.␈α∞Evaluation␈α∞is␈α∞an␈α∞algorithmic␈α∞idea;␈α∞there␈α∞is␈α∞no␈α∞idea␈α∞of␈α∞evaluation
␈↓ ↓H␈↓involved␈α∞with␈α∞the␈α∞concept␈α
of␈α∞"function".␈α∞ To␈α∞reinforce␈α
this␈α∞algorithmic␈α∞interpretation␈α∞we␈α∞will␈α
say
␈↓ ↓H␈↓things␈α∂like␈α∂ a function␈α∂returns␈α∞as␈α∂value ..."␈α∂meaning␈α∂the␈α∞algorithmic␈α∂representation␈α∂of␈α∂a␈α∞function
␈↓ ↓H␈↓computes and produces a value.
␈↓ ↓H␈↓We␈αhave␈αtwo␈αstrict,␈αunary␈α␈↓↓selector␈↓␈αfunctions,␈α␈↓αcar␈↓␈αand␈α␈↓αcdr␈↓␈↓π 15␈↓,␈αfor␈αtraversing␈αLISP-trees.␈α We␈αalready
␈↓ ↓H␈↓know␈αthe␈α
meaning␈αof␈α
"strict";␈αa␈α
unary␈αfunction␈αexpects␈α
␈↓↓one␈↓␈αargument;␈α
and␈αa␈α
selector␈αfunction␈α
is␈αa
␈↓ ↓H␈↓data␈α
structure␈α
manipulating␈αfunction␈α
which␈α
will␈αselect␈α
a␈α
component␈αof␈α
a␈α
composite␈α
data␈αstructure.
␈↓ ↓H␈↓Such␈α
LISP␈α
functions␈α
are␈αcalled␈α
selectors␈α
since␈α
they␈α
will␈α␈↓↓select␈↓␈α
components␈α
of␈α
non-atomic␈αelements␈α
of
␈↓ ↓H␈↓␈↓<sexpr>␈↓.␈α∞ Thus␈α∞␈↓αcar␈↓␈α∞and␈α∞␈↓αcdr␈↓␈α∞are␈α∞partial␈α∞functions␈α∞over␈α∞␈↓<sexpr>␈↓:␈α∞they␈α∞give␈α∞values␈α∞in␈α
␈↓<sexpr>␈↓
␈↓ ↓H␈↓only for non-atomic arguments; they give ␈↓λB␈↓ whenever they are presented with an atomic argument.
␈↓ ↓H␈↓When␈α∞given␈α∞a␈α∞non-atomic␈α∞argument,␈α∞␈↓α(␈↓λα␈↓α␈α∞.␈α∞␈↓λβ␈↓α)␈↓,␈α∞␈↓αcar␈↓␈α∞returns␈α∞as␈α∞value␈α∞the␈α∞first␈α∞subexpression,␈α∞␈↓λα␈↓;␈α
␈↓αcdr␈↓
␈↓ ↓H␈↓(pronounced could-er) returns as value the second sub-expression ␈↓λβ␈↓.
␈↓ ↓H␈↓For example:␈↓ ∧|␈↓αcar[(A . B)] = A car[A] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ∧"cdr[(A . B)] = B cdr[(A .(B . C))] = (B . C)
␈↓ ↓H␈↓α␈↓ ¬&car[((A . B) . C)] = (A . B)
␈↓ ↓H␈↓We␈α∪will␈α∪include␈α∪functional␈α∪composition␈α∪as␈α∩a␈α∪notation␈α∪for␈α∪combining␈α∪LISP␈α∪expressions.␈α∩ The
␈↓ ↓H␈↓composition␈αof␈αtwo␈α
unary␈αfunctions␈α␈↓αf␈↓␈α
and␈α␈↓αg␈↓␈αis␈αanother␈α
function,␈αdenoted␈αby␈α
␈↓αf␈↓∞o␈↓αg␈↓.␈αThe␈αvalue␈α
of␈αan
␈↓ ↓H␈↓expression,␈α
␈↓αf␈↓∞o␈↓αg[x]␈↓,␈α
is␈α
the␈αvalue␈α
of␈α
␈↓αf[g[x]]␈↓.␈α
That␈αis,␈α
the␈α
value␈α
of␈α␈↓αf␈↓∞o␈↓αg[x]␈↓␈α
is␈α
a␈α
␈↓αz␈↓␈αsuch␈α
that␈α
␈↓αy␈↓␈α
is␈αthe␈α
value
␈↓ ↓H␈↓of␈α␈↓αg[x]␈↓␈αand␈α
␈↓αz␈↓␈αis␈αthe␈α
value␈αof␈α␈↓αf[y]␈↓.␈α
␈↓αf␈↓∞o␈↓αg␈↓␈αmay␈αbe␈α
undefined␈αfor␈αseveral␈α
reasons:␈α␈↓αg[x]␈↓␈αmay␈αbe␈α
undefined
␈↓ ↓H␈↓and ␈↓αf␈↓ is strict, or ␈↓αf[y]␈↓ may be undefined.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 14␈↓ The syntax equations for forms are given on page 17.
␈↓ ↓H␈↓␈↓π 15␈↓␈α
These␈α
names␈α
are␈α
hold-overs␈αfrom␈α
the␈α
original␈α
implementation␈α
of␈αLISP␈α
on␈α
an␈α
IBM␈α
704.␈αThat
␈↓ ↓H␈↓machine␈αhad␈αpartial-word␈α
instructions␈αto␈αreference␈α
the␈α␈↓a␈↓ddress␈αand␈α
␈↓d␈↓ecrement␈αparts␈αof␈α
a␈αmachine
␈↓ ↓H␈↓location.␈α
The␈α
␈↓αa␈↓␈α
of␈α
␈↓αcar␈↓␈α
comes␈α
from␈α
"address",␈α
the␈α
␈↓αd␈↓␈α
of␈α
␈↓αcdr␈↓␈α
comes␈α
from␈α
"decrement".␈α
The␈α
␈↓αc␈↓␈α
and␈α
␈↓αr␈↓␈α
come
␈↓ ↓H␈↓from "contents of" and "register". Thus ␈↓αcar␈↓ could be read "contents of address part of register".
␈↓ ↓H␈↓␈↓↓14 Symbolic expressions␈↓ 41.4␈↓
␈↓ ↓H␈↓Here are some examples of composition:
␈↓ ↓H␈↓α␈↓ β=car␈↓∞o␈↓αcdr[(A .(B . C))] = car[cdr[(A .(B . C))]] = car[(B . C)] = B
␈↓ ↓H␈↓α␈↓ β;cdr␈↓∞o␈↓αcdr[(A .(C . B))] = cdr[cdr[(A .(C . B))]] = cdr[(C . B)] = B
␈↓ ↓H␈↓α␈↓ ¬lcdr[cdr[A]] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ¬Jcar[cdr[(A . B)]] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ∧<car[cons[X;A]] = X cdr[cons[Y;X]] = X .
␈↓ ↓H␈↓All␈αthe␈αfunctions␈αin␈αthese␈αexamples␈αare␈αstrict;␈αfor␈αthat␈αreason,␈αif␈α␈↓αg[x]␈↓␈αgives␈α␈↓λB␈↓␈αthen␈αthe␈αcomposition
␈↓ ↓H␈↓␈↓αf␈↓∞o␈↓αg[x]␈↓ also gives ␈↓λB␈↓. That need not be the case if ␈↓αf␈↓ is non-strict.
␈↓ ↓H␈↓The␈αcomposition␈αof␈α
many␈α␈↓αcar␈↓␈αand␈α␈↓αcdr␈↓␈α
functions␈αoccurs␈αso␈αfrequently␈α
that␈αan␈αabbreviation␈αhas␈α
been
␈↓ ↓H␈↓developed.␈α
Given␈αsuch␈α
a␈αcomposition,␈α
we␈αselect␈α
in␈α
left-to-right␈αorder,␈α
the␈αrelevant␈α
␈↓αa␈↓'s␈αand␈α
␈↓αd␈↓'s␈αin␈α
the
␈↓ ↓H␈↓␈↓αcar␈↓'s␈α
and␈α
␈↓αcdr␈↓'s.␈αWe␈α
sandwich␈α
this␈αstring␈α
of␈α
␈↓αa␈↓'s␈αand␈α
␈↓αd␈↓'s␈α
between␈αa␈α
left-hand␈α
␈↓αc␈↓␈αand␈α
a␈α
right-hand␈α␈↓αr␈↓␈α
and
␈↓ ↓H␈↓give the composition this name.
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓α␈↓ ¬Gcadr[x] <= car[cdr[x]]
␈↓ ↓H␈↓α␈↓ ¬!caddr[x] <= car[cdr[cdr[x]]]
␈↓ ↓H␈↓α␈↓ ¬Gcdar[x] <= cdr[car[x]]
␈↓ ↓H␈↓These␈α⊂compositions␈α⊂are␈α∂also␈α⊂called␈α⊂␈↓↓␈↓αcar-cdr-␈↓↓chains␈↓,␈α∂and␈α⊂are␈α⊂useful␈α∂in␈α⊂traversing␈α⊂LISP-trees.␈α∂The
␈↓ ↓H␈↓"<="-␈α
notation␈α
is␈α
to␈α
be␈α
read␈α
"is␈α
defined␈α
to␈α
be␈α
the␈α
function␈α
...".␈α
This␈α
notation␈α
is␈α
only␈α∞a␈α
temporary
␈↓ ↓H␈↓convenience␈α⊂and␈α⊂not␈α⊂part␈α⊂of␈α⊂LISP.␈α⊂ Soon␈α⊂we␈α∂will␈α⊂study␈α⊂what␈α⊂is␈α⊂involved␈α⊂in␈α⊂giving␈α⊂and␈α∂using
␈↓ ↓H␈↓definitions in LISP (Section 3.4). For the moment intuition will suffice.
␈↓ ↓H␈↓It is useful to introduce some terminology for the components of a function definition. Let
␈↓ ↓H␈↓α␈↓ ¬gf[x␈↓β1␈↓α; ...; x␈↓βn␈↓α] <= ␈↓λx␈↓α
␈↓ ↓H␈↓represent␈α⊂a␈α⊂typical␈α⊂definition.␈α⊂The␈α⊂␈↓↓name␈↓␈α⊂of␈α⊂the␈α⊂function␈α⊂is␈α⊂␈↓αf␈↓;␈α⊂the␈α⊂␈↓↓body␈↓␈α⊂of␈α⊂the␈α⊂function␈α⊂is␈α⊂the
␈↓ ↓H␈↓expression␈α
␈↓λx␈↓.␈α
The␈α
list␈α
␈↓α[x␈↓β1␈↓α;␈α...;␈α
x␈↓βn␈↓α]␈↓␈α
appearing␈α
after␈α
the␈αfunction␈α
name␈α
is␈α
called␈α
the␈α␈↓↓formal␈α
parameter␈↓
␈↓ ↓H␈↓list.␈α
The␈α
elements␈α∞of␈α
the␈α
formal␈α
parameter␈α∞list␈α
are␈α
called␈α
formal␈α∞parameters␈α
and␈α
will␈α
play␈α∞a␈α
role
␈↓ ↓H␈↓similar␈αto␈α
that␈αof␈αvariables␈α
in␈αmathematics␈↓π 16␈↓.␈α
Therefore␈αwe␈αwill␈α
also␈αrefer␈α
to␈αformal␈αparameters␈α
as
␈↓ ↓H␈↓variables.␈α Lower-case␈αidentifiers␈↓π 17␈↓␈αwill␈αbe␈αused␈αas␈αvariables␈αand␈αfunction␈αnames.␈α So␈αfor␈αexample
␈↓ ↓H␈↓␈↓αY␈↓␈α
and␈α␈↓αCAR␈↓␈α
are␈αatoms;␈α
␈↓αy␈↓␈αand␈α
␈↓αcar␈↓␈α
could␈αbe␈α
used␈αas␈α
variables.␈α Be␈α
clear␈αon␈α
the␈α
distinction␈αbetween
␈↓ ↓H␈↓LISP␈αvariables␈αlike␈α␈↓αx,␈αy␈↓␈αor␈α␈↓αfoo␈↓,␈αand␈αthe␈αmatch␈αvariables␈↓π 18␈↓␈αlike␈α␈↓λα␈↓␈αor␈α␈↓λβ␈↓.␈α For␈α␈↓λα␈↓␈αand␈α␈↓λβ␈↓␈αranging␈αover
␈↓ ↓H␈↓S-expressions,␈α⊂␈↓α(␈↓λα␈↓α . ␈↓λβ␈↓α)␈↓␈α⊂is␈α∂a␈α⊂well␈α⊂formed␈α∂S-expr.␈α⊂The␈α⊂construction,␈α∂␈↓α(x . y)␈↓,␈α⊂is␈α⊂␈↓↓not␈↓␈α⊂well-formed,␈α∂but
␈↓ ↓H␈↓␈↓αcons[x;y]␈↓ is correct.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 16␈↓␈αThe␈αbehavior␈αof␈αformal␈αparameters␈αand␈αvariables␈αis␈α␈↓↓not␈↓␈αidentical.␈αWe␈αwill␈αsay␈αmore␈αabout␈αthe
␈↓ ↓H␈↓distinction in Section 4.1.
␈↓ ↓H␈↓α␈↓π 17␈↓α ␈↓See page 17 for the BNF equations for <identifier>.
␈↓ ↓H␈↓␈↓π 18␈↓ also called meta-variables
␈↓ ↓H␈↓␈↓↓1.4␈↓ λyPrimitive Functions 15␈↓
␈↓ ↓H␈↓A function is ␈↓↓applied␈↓ using the common notation of ␈↓↓function application␈↓:
␈↓ ↓H␈↓α␈↓ ε f[a␈↓β1␈↓α; ...; a␈↓βn␈↓α]
␈↓ ↓H␈↓The␈α␈↓αa␈↓βi␈↓'s␈α
are␈αcalled␈α␈↓↓actual␈α
parameters␈↓;␈αfor␈αan␈α
application␈αto␈αbe␈α
well␈αformed,␈αthe␈α
actual␈αparameters
␈↓ ↓H␈↓must␈α
agree␈αin␈α
number␈α
with␈αthe␈α
formal␈α
parameters␈αof␈α
the␈α
definition␈αand␈α
they␈α
are␈αto␈α
be␈αassociated␈α
in
␈↓ ↓H␈↓a␈αone-for-one␈αorder,␈α␈↓αa␈↓βi␈↓␈αwith␈α
␈↓αx␈↓βi␈↓.␈α Thus␈αin␈αthe␈αexpression␈α
␈↓αcar[cdr[(A . B)]]␈↓␈αthe␈αactual␈αparameter␈αto␈α
the
␈↓ ↓H␈↓␈↓αcar␈↓␈αfunction␈αis␈α␈↓αcdr[(A . B)]␈↓,␈αand␈αthe␈αactual␈αparameter␈αto␈α␈↓αcdr␈↓␈αis␈α␈↓α(A . B)␈↓.␈α How␈αthe␈αactual␈αparameters
␈↓ ↓H␈↓are to be treated will be a large part of our study.
␈↓ ↓H␈↓Again,␈α
it␈α
is␈α∞convenient␈α
to␈α
introduce␈α∞some␈α
terminology␈α
to␈α∞distinguish␈α
between␈α
an␈α∞algorithmic␈α
idea
␈↓ ↓H␈↓and␈α∪its␈α∩mathematical␈α∪counterpart.␈α∩The␈α∪phrase␈α∩"function call"␈α∪is␈α∩used␈α∪to␈α∩name␈α∪the␈α∩procedural
␈↓ ↓H␈↓counterpart␈αto␈α
"function application".␈α LISP␈α
is␈αcalled␈αan␈α
␈↓↓applicative language␈↓␈αsince␈α
it␈αis␈α
based␈αon
␈↓ ↓H␈↓the␈α∂idea␈α∂of␈α∂function␈α∂application.␈α∂ Mathematically␈α∞speaking,␈α∂a␈α∂composition␈α∂of␈α∂functions␈α∂is␈α∞simply
␈↓ ↓H␈↓another␈α∂function␈α∞-- i.e., a␈α∂mapping --␈α∂and␈α∞therefore␈α∂nothing␈α∞need␈α∂be␈α∂said␈α∞about␈α∂how␈α∂to␈α∞compute
␈↓ ↓H␈↓composed␈α∪functions.␈α∪From␈α∪a␈α∪computational␈α∪point␈α∪of␈α∪view,␈α∪we␈α∪want␈α∪to␈α∪express␈α∀evaluation␈α∪of
␈↓ ↓H␈↓expressions␈αinvolving␈α
composed␈αfunctions␈α
in␈αterms␈α
of␈αthe␈α
evaluation␈αof␈α
subexpressions.␈αThis␈α
would
␈↓ ↓H␈↓allow␈α⊂us␈α∂to␈α⊂describe␈α∂a␈α⊂complex␈α⊂computation␈α∂in␈α⊂terms␈α∂of␈α⊂an␈α∂appropriate␈α⊂sequence␈α⊂of␈α∂subsidiary
␈↓ ↓H␈↓computations.␈α One␈α
of␈αthe␈αmore␈α
natural␈αways␈α
to␈αevaluate␈αexpressions␈α
involving␈αcompositions␈α
is␈αto
␈↓ ↓H␈↓evaluate␈α
the␈α
inner-most␈α
expressions␈α
first,␈α
then␈α
work␈α
outwards.␈α
Assume␈α
arguments␈α
to␈α
multi-argument
␈↓ ↓H␈↓functions are evaluated in left-to-right order. Thus:
␈↓ ↓H␈↓α␈↓ αXcons[car[(A . B)];cdr[(A . (1 . 2))]]␈↓ ε8␈↓reduces to␈↓α cons[A;cdr[(A . (1 . 2))]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ε8␈↓reduces to␈↓α cons[A;(1 . 2)]
␈↓ ↓H␈↓α␈↓ αX␈↓ ε8␈↓reduces to␈↓α (A . (1 . 2))
␈↓ ↓H␈↓Evaluation␈α∞may␈α∞seem␈α∞to␈α∞be␈α∞a␈α∞simple␈α∞operation␈α
but␈α∞in␈α∞fact␈α∞evaluation␈α∞is␈α∞a␈α∞very␈α∞complex␈α
process.
␈↓ ↓H␈↓The␈α
value␈α
of␈α
an␈α
expression␈αmay␈α
depend␈α
on␈α
the␈α
␈↓↓order␈↓␈α
in␈αwhich␈α
we␈α
do␈α
things.␈α
For␈αexample,␈α
consider
␈↓ ↓H␈↓the␈α∩evaluation␈α∩of␈α∩␈↓αsecond[car[A]; B]␈↓␈α∩where␈α∩␈↓αsecond[x;y] <= y␈↓.␈α∩ If␈α∩we␈α∩expect␈α∩␈↓αsecond␈↓␈α∩to␈α∩be␈α∩a␈α∩strict
␈↓ ↓H␈↓function,␈α∂then␈α∂␈↓αsecond[car[A]; B]␈↓␈α∂must␈α⊂return␈α∂␈↓λB␈↓␈α∂even␈α∂though␈α∂it␈α⊂is␈α∂reasonable␈α∂to␈α∂believe␈α⊂that␈α∂the
␈↓ ↓H␈↓value␈αof␈αthe␈αcomputation␈αshould␈αbe␈α␈↓αB␈↓␈αsince␈α␈↓αsecond␈↓␈αdoes␈αnot␈αvisibly␈αdepend␈αon␈αthe␈αvalue␈αof␈αits␈αfirst
␈↓ ↓H␈↓parameter.␈α
It␈α
appears␈αthat␈α
if␈α
we␈α
postponed␈αthe␈α
evaluation␈α
of␈α
the␈αarguments␈α
until␈α
those␈αvalues␈α
were
␈↓ ↓H␈↓actually␈α
needed,␈α
then␈α
at␈αleast␈α
this␈α
problem␈α
would␈α
be␈αsolved.␈α
However,␈α
the␈α
consequences␈αof␈α
defining
␈↓ ↓H␈↓a␈αfunction␈αto␈α
be␈αstrict␈αare␈α
severe;␈αthey␈αcannot␈α
be␈αsidestepped␈αby␈α
resorting␈αto␈αdifferent␈α
schemes␈αfor
␈↓ ↓H␈↓evaluating␈αarguments.␈αThere␈αis␈αan␈αalternative,␈αbut␈αnot␈αparticularly␈αattractive,␈αstrategy␈αfor␈αassigning
␈↓ ↓H␈↓strictness:␈α
we␈αcould␈α
examine␈αthe␈α
body␈αof␈α
the␈αfunction;␈α
if␈αthe␈α
function␈αuses␈α
all␈αits␈α
parameters,␈αthen
␈↓ ↓H␈↓it's␈αstrict.␈αIf␈αthe␈αfunction␈αdoesn't␈αdepend␈αon␈αone␈αor␈αmore␈αparameters,␈αthen␈αit's␈αnon-strict.␈αThus␈αwith
␈↓ ↓H␈↓this␈α∂interpretation,␈α∂␈↓αsecond␈↓␈α∂␈↓↓is␈↓␈α∂non-strict.␈α∂ We␈α∞prefer␈α∂the␈α∂initial␈α∂interpretation,␈α∂reasoning␈α∂that,␈α∂if␈α∞a
␈↓ ↓H␈↓function␈α
is␈αpassed␈α
bad␈αinformation,␈α
then␈αwe␈α
wish␈αto␈α
know␈αabout␈α
it,␈αeven␈α
if␈αthe␈α
function␈α
does␈αnot
␈↓ ↓H␈↓use that specious result.
␈↓ ↓H␈↓␈↓↓16 Symbolic expressions␈↓ 41.4␈↓
␈↓ ↓H␈↓Strictness␈α∂is␈α∂closely␈α∂related␈α∂to␈α∂evaluation␈α∞schemes␈α∂for␈α∂parameter␈α∂passing.␈α∂ Here␈α∂are␈α∂two␈α∞common
␈↓ ↓H␈↓techniques:
␈↓ ↓H␈↓␈↓ CBV␈↓␈↓ α(Evaluate the arguments to a function; pass those evaluated arguments to the function.
␈↓ ↓H␈↓This␈α∂scheme,␈α⊂called␈α∂␈↓ C␈↓all␈α⊂␈↓ B␈↓y␈α∂␈↓ V␈↓alue,␈α⊂is␈α∂what␈α⊂we␈α∂were␈α⊂informally␈α∂using␈α⊂to␈α∂evaluate␈α⊂the␈α∂previous
␈↓ ↓H␈↓examples.
␈↓ ↓H␈↓An alternative evaluation process is ␈↓ C␈↓all ␈↓ B␈↓y ␈↓ N␈↓ame:
␈↓ ↓H␈↓␈↓ CBN␈↓␈↓ α(Pass the unevaluated arguments into the body of the function.
␈↓ ↓H␈↓Assuming␈α␈↓αsecond␈↓␈α
is␈αdefined␈α
to␈αbe␈α
strict,␈αthen␈α
␈↓αsecond[car[A]; B]␈↓␈αyields␈α
␈↓λB␈↓␈αunder␈α
either␈α␈↓ CBV␈↓␈αor␈α
␈↓ CBN␈↓.
␈↓ ↓H␈↓However␈α
if␈α
we␈αdefine␈α
␈↓αsecond␈↓␈α
to␈αbe␈α
non-strict␈α
then␈α
␈↓ CBV␈↓␈αand␈α
␈↓ CBN␈↓␈α
will␈αboth␈α
give␈α
value␈α
␈↓αB␈↓.␈α With
␈↓ ↓H␈↓␈↓ CBV␈↓, ␈↓αx␈↓ is bound to ␈↓λB␈↓; while with ␈↓ CBN␈↓ ␈↓αx␈↓ is bound to ␈↓αcar[A]␈↓.
␈↓ ↓H␈↓Further␈α
relationships␈α
between␈α
evaluation␈α
schemes␈αand␈α
strictness␈α
will␈α
be␈α
investigated.␈α
On␈αpage 21
␈↓ ↓H␈↓we␈αdiscuss␈αnon-terminating␈αcomputations.␈α In␈α
Chapter 3␈αwe␈αwill␈αdiscuss␈αevaluation␈α
techniques␈αand
␈↓ ↓H␈↓will␈α∂give␈α∂a␈α∂precise␈α∂characterization␈α∂of␈α∂the␈α∂evaluation␈α∂of␈α∂LISP␈α∂expressions.␈α∂ On␈α∂page 19␈α∂we␈α∞will
␈↓ ↓H␈↓introduce␈α∂a␈α∂non-strict␈α∂language␈α∂construct␈α∂but,␈α⊂until␈α∂that␈α∂time,␈α∂intuitive␈α∂application␈α∂of␈α⊂␈↓ CBV␈↓␈α∂will
␈↓ ↓H␈↓suffice.
␈↓ ↓H␈↓We␈α
must␈α
exercise␈α
care␈α
when␈α
discussing␈α
the␈α
process␈α
of␈α
evaluation;␈α
the␈α
function␈α
we␈αare␈α
characterizing
␈↓ ↓H␈↓by computing its values will often depend on our choice of evaluation scheme.
␈↓ ↓H␈↓␈↓↓1.4␈↓ λyPrimitive Functions 17␈↓
␈↓ ↓H␈↓Before␈α⊂introducing␈α⊂a␈α⊃further␈α⊂class␈α⊂of␈α⊃LISP␈α⊂expressions␈α⊂we␈α⊂summarize␈α⊃the␈α⊂syntax␈α⊂of␈α⊃the␈α⊂LISP
␈↓ ↓H␈↓expressions allowed so far:
␈↓ ↓H␈↓<form>␈↓ βH::= <constant> | <application> | <variable>
␈↓ ↓H␈↓<constant>␈↓ βH::= <sexpr> (where <sexpr> is given on page 6)
␈↓ ↓H␈↓<application>␈↓ βH::= <function-part>[<arg>; ...;<arg>]
␈↓ ↓H␈↓<function-part>␈↓ βH::= <identifier>
␈↓ ↓H␈↓<arg>␈↓ βH::= <form>
␈↓ ↓H␈↓<variable>␈↓ βH::= <identifier>
␈↓ ↓H␈↓<identifier>␈↓ βH::= <letter> | <identifier><letter> | <identifier><digit>
␈↓ ↓H␈↓<letter>␈↓ βH::= ␈↓αa | b | c ... | z ␈↓
␈↓ ↓H␈↓<digit>␈↓ βH::= ␈↓α1 | 2 | ... | 9
␈↓ ↓H␈↓The␈α
use␈αof␈α
ellipses␈αin␈α
the␈αlast␈α
equation␈αis␈α
an␈α
abbreviation␈αwe␈α
have␈αseen␈α
before.␈α The␈α
use␈αof␈α
ellipses
␈↓ ↓H␈↓in␈α
the␈α
<application>␈α
equation␈α
is␈α
different.␈α
It␈α
is␈α
an␈α
abbreviation␈α
meaning␈α
"zero␈α
or␈α
more␈α
occurrences".
␈↓ ↓H␈↓Thus␈α
the␈α
equation␈αmeans␈α
an␈α
<application>␈αis␈α
a␈α
<function-part>␈α
followed␈αby␈α
the␈α
symbol␈α"["␈α
followed
␈↓ ↓H␈↓by␈αzero␈αor␈αmore␈α<arg>'s␈αfollowed␈αby␈αthe␈αsymbol␈α"]".␈α This␈αuse␈αof␈αellipses␈αcan␈αalways␈αbe␈αreplaced␈αby
␈↓ ↓H␈↓a sequence of BNF equations. for example, this instance can be replaced by:
␈↓ ↓H␈↓<application>␈↓ βH::= <function-part>[<arg-list>] | <function-part>[ ]
␈↓ ↓H␈↓<arg-list>␈↓ βH::= <arg> | <arg-list>;<arg>
␈↓ ↓H␈↓To␈αimprove␈αreadability␈αwe␈αwill␈αfrequently␈αviolate␈αthese␈αsyntax␈αequations,␈αallowing␈α
function␈αnames
␈↓ ↓H␈↓containing␈αspecial␈αcharacters,␈αe.g.␈α␈↓αfact*␈↓,␈α␈↓αfib␈↓λ'␈↓␈αor␈α+␈α;␈αor␈αwriting␈α␈↓αx+y␈↓␈αinstead␈αof␈α␈↓α+[x;y]␈↓.␈α No␈αattempt␈αwill
␈↓ ↓H␈↓be made to characterize these violations; occurrences of them should be clear from context.
␈↓ ↓H␈↓Notice␈αthat␈αthe␈αclass␈α<form>␈αis␈αa␈αcollection␈αof␈αLISP␈αexpressions␈αwhich␈αcan␈αbe␈αevaluated.␈αA␈α<form>
␈↓ ↓H␈↓is either:
␈↓ ↓H␈↓␈↓ α_␈↓↓1.␈↓ a constant: the value is that constant.
␈↓ ↓H␈↓␈↓ α_␈↓↓2.␈↓ an application: we've said a bit about evaluation schemes for these constructs.
␈↓ ↓H␈↓␈↓ α_␈↓↓3.␈↓ a variable: a variable in LISP will typically have an associated value in some environment.
␈↓ ↓H␈↓We will wait to Section 3.4 for a precise description.
␈↓ ↓H␈↓␈↓↓18 Symbolic expressions␈↓ 41.4␈↓
␈↓ ↓H␈↓An␈α⊃important␈α⊃constraint␈α⊃on␈α⊃LISP␈α⊃forms␈α⊃which␈α⊃is␈α⊃not␈α⊃covered␈α⊃by␈α⊃the␈α⊃syntax␈α⊃equations␈α⊃is␈α⊂the
␈↓ ↓H␈↓requirement␈αthat␈αfunctions␈αare␈αdefined␈αas␈αbeing␈αn-ary␈αfor␈αsome␈α␈↓↓fixed␈↓␈αn.␈α Any␈αn-ary␈αLISP␈αfunction
␈↓ ↓H␈↓must␈αhave␈α␈↓↓exactly␈↓␈αn␈αarguments␈αpresented␈αto␈αit␈αwhenever␈αit␈αis␈αapplied.␈α Thus␈α␈↓αcons[A],␈αcons[A;B;C],
␈↓ ↓H␈↓α␈↓and ␈↓αcar[A;B]␈↓ are all ill-formed expressions and therefore denote ␈↓λB␈↓.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Discuss ␈↓αcons[car[x];cdr[x]] = x␈↓.
␈↓ ↓H␈↓II. Discuss ␈↓αcons[car[␈↓λα␈↓α];cdr[␈↓λα␈↓α]] = ␈↓λα␈↓.
␈↓ ↓H␈↓␈↓ ∧*␈↓↓1.5 Predicates and Conditional Expressions␈↓
␈↓ ↓H␈↓We␈α∂cannot␈α∂generate␈α∂a␈α∂very␈α∂exciting␈α∂theory␈α⊂based␈α∂simply␈α∂on␈α∂␈↓αcar,␈α∂cdr,␈↓␈α∂and␈α∂␈↓αcons␈α∂␈↓␈α⊂with␈α∂functional
␈↓ ↓H␈↓composition.␈α⊂Before␈α⊂we␈α⊂can␈α∂write␈α⊂reasonably␈α⊂interesting␈α⊂algorithms␈α∂we␈α⊂must␈α⊂have␈α⊂some␈α⊂way␈α∂of
␈↓ ↓H␈↓performing␈α
conditional␈αactions.␈α
To␈αdo␈α
this␈α
we␈αfirst␈α
need␈αpredicates.␈α
A␈α
LISP␈αpredicate␈α
is␈αa␈α
function
␈↓ ↓H␈↓returning␈αa␈αvalue␈αrepresenting␈αtruth␈αor␈αfalsity.␈α We␈αwill␈αrepresent␈αthe␈αconcepts␈αof␈αtrue␈αand␈αfalse␈αby
␈↓ ↓H␈↓␈↓
t␈↓␈αand␈α␈↓
f␈↓␈αrespectively.␈αSince␈αthese␈αtruth␈αvalues␈αare␈αdistinct␈αfrom␈αelements␈αof␈α␈↓ S␈↓,␈αwe␈αwill␈αset␈αup␈αa␈αnew
␈↓ ↓H␈↓domain␈α␈↓ Tr␈↓␈α
which␈αwill␈αconsist␈α
of␈αthe␈αelements,␈α
␈↓
t␈↓␈αand␈α
␈↓
f␈↓.␈αAs␈αusual␈α
the␈αextra␈αelement␈α
␈↓λB␈↓␈αis␈αincluded␈α
so
␈↓ ↓H␈↓that we may talk about partial predicates just as we talked about partial functions on ␈↓<sexpr>␈↓.␈↓π 19␈↓.
␈↓ ↓H␈↓LISP␈αhas␈αtwo␈αprimitive␈αpredicates.␈α
The␈αfirst␈αis␈αa␈αstrict␈α
unary␈αpredicate␈αnamed␈α␈↓αatom␈↓;␈α␈↓αatom␈↓␈α
is␈αtotal
␈↓ ↓H␈↓over␈α∀␈↓<sexpr>␈↓,␈α∃and␈α∀is␈α∀a␈α∃special␈α∀kind␈α∀of␈α∃predicate␈α∀called␈α∀a␈α∃␈↓↓recognizer␈↓␈α∀or␈α∃a␈α∀␈↓↓discriminator␈↓.
␈↓ ↓H␈↓Recognizers␈α∂are␈α∂used␈α∂to␈α∂determine␈α∂the␈α∂type␈α⊂of␈α∂an␈α∂instance␈α∂of␈α∂a␈α∂data␈α∂structure.␈α∂ Thus␈α⊂␈↓αatom␈↓␈α∂will
␈↓ ↓H␈↓return ␈↓
t␈↓ if the argument denotes an atom, and will return ␈↓
f␈↓ if the argument is a non-atomic S-expr.
␈↓ ↓H␈↓α␈↓ ¬.atom[A] = atom[NIL] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ¬←atom[(A . B)] = ␈↓
f␈↓α
␈↓ ↓H␈↓α␈↓ ¬Batom[car[(A . B)]] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ¬⎇atom[␈↓λB␈↓α] = ␈↓λB␈↓α
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 19␈↓␈α∂A␈α∂word␈α∂for␈α⊂the␈α∂previous␈α∂LISP␈α∂user:␈α∂our␈α⊂use␈α∂of␈α∂␈↓
t␈↓␈α∂and␈α∂␈↓
f␈↓␈α⊂marks␈α∂our␈α∂first␈α∂major␈α⊂break␈α∂from
␈↓ ↓H␈↓current␈αLISP␈αfolklore.␈α The␈αtypical␈αLISP␈αtrick␈αis␈αto␈αuse␈αthe␈αatoms␈α␈↓αT␈↓␈αand␈α␈↓αNIL␈↓␈αrather␈αthan␈α␈↓
t␈↓␈αand␈α␈↓
f␈↓
␈↓ ↓H␈↓as␈α∂truth␈α∂values.␈α∂ Our␈α∂convention␈α∂will␈α∂disallow␈α∂some␈α∂mixed␈α∂compositions␈α∂of␈α∂LISP␈α∂functions␈α∞and
␈↓ ↓H␈↓predicates.
␈↓ ↓H␈↓␈↓↓1.5␈↓ εsPredicates and Conditional Expressions 19␈↓
␈↓ ↓H␈↓What␈α
should␈α
we␈α
do␈α
about␈α
the␈α
value␈α
of␈α
constructs␈α
like:␈α
␈↓αcons[atom[A]; A]␈↓?␈α
␈↓αatom[A]␈↓␈α
gives␈α
␈↓
t␈↓,␈α
but␈α∞␈↓
t␈↓␈α
is
␈↓ ↓H␈↓not␈αan␈α
element␈αof␈α
␈↓ S␈↓␈αand␈α
thus␈αis␈α
not␈αappropriate␈αas␈α
an␈αargument␈α
to␈α␈↓αcons␈↓.␈α
Using␈αour␈α
discussion␈αof
␈↓ ↓H␈↓page 11, we extend the domains of the S-expr primitives to
␈↓ ↓H␈↓␈↓ εα␈↓ S␈↓β1␈↓ = ␈↓ S␈↓∪␈↓ Tr␈↓
␈↓ ↓H␈↓α␈↓For example, for ␈↓αs␈↓λε␈↓ Tr␈↓:␈↓α
␈↓ ↓H␈↓α␈↓ ∧Kcar[s] = car[␈↓λB␈↓α], cons[s; A] = cons[␈↓λB␈↓α; A]␈↓
␈↓ ↓H␈↓Since all those functions were strict with respect to undefined we have:
␈↓ ↓H␈↓α␈↓ ε∧atom[␈↓
t␈↓α] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ¬mcons[␈↓λB␈↓α; A] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ¬mcons[A; ␈↓λB␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓Notice␈αthat␈α
we␈αnow␈αhave␈α
␈↓↓two␈↓␈αseparate␈αdomains:␈α
S-expressions␈αand␈αtruth␈α
values.␈α Since␈αwe␈α
will␈αbe
␈↓ ↓H␈↓writing␈α
functions␈αover␈α
several␈αdomains␈α
we␈αwill␈α
need␈αa␈α
general␈αrecognizer␈α
for␈αeach␈α
domain␈αto␈α
assure
␈↓ ↓H␈↓that␈α
the␈α
operations␈α
defined␈αon␈α
each␈α
abstract␈α
data␈α
structure␈αare␈α
properly␈α
applied.␈α
Thus␈αwe␈α
introduce
␈↓ ↓H␈↓the␈α∞recognizer␈α∞␈↓αissexpr␈↓␈α∞which␈α∞will␈α∞give␈α∞␈↓
t␈↓␈α∞on␈α∞the␈α∞domain␈α∞of␈α∞S-exprs,␈α∞␈↓
f␈↓␈α∞for␈α∞for␈α∞any␈α∞element␈α∞not␈α∞in
␈↓ ↓H␈↓␈↓<sexpr>␈↓ and will give ␈↓λB␈↓ for ␈↓λB␈↓.
␈↓ ↓H␈↓α␈↓ ¬issexpr[(A . B)] = issexpr[A] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ¬{issexpr[␈↓
t␈↓α] = ␈↓
f␈↓α
␈↓ ↓H␈↓α␈↓ ¬nissexpr[␈↓λB␈↓α] = ␈↓λB␈↓α
␈↓ ↓H␈↓Another␈α
primitive␈α
predicate␈α
we␈α
need␈α
is␈α
named␈α
␈↓αeq␈↓.␈α It␈α
is␈α
a␈α
strict␈α
binary␈α
predicate,␈α
partial␈α
over␈αthe␈α
set
␈↓ ↓H␈↓␈↓<sexpr>␈↓;␈α⊂it␈α⊂will␈α∂give␈α⊂a␈α⊂truth␈α∂value␈α⊂only␈α⊂if␈α∂its␈α⊂arguments␈α⊂are␈α∂both␈α⊂atomic.␈α⊂ It␈α∂returns␈α⊂␈↓
t␈↓␈α⊂if␈α∂the
␈↓ ↓H␈↓arguments␈αdenote␈αthe␈αsame␈αatom;␈αit␈αreturns␈α␈↓
f␈↓␈αif␈αthe␈αarguments␈αrepresent␈αdifferent␈αatoms.␈α ␈↓αeq␈↓␈αyields
␈↓ ↓H␈↓␈↓λB␈↓ if either argument to ␈↓αeq␈↓ denotes an element not in the set ␈↓<atom>␈↓.
␈↓ ↓H␈↓α␈↓ ∧qeq[A;A] = ␈↓
t␈↓α eq[A;B] = ␈↓
f␈↓α
␈↓ ↓H␈↓α␈↓ ∧&eq[(A . B); A] = ␈↓λB␈↓α eq[(A . B);(A . B)] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ∧ueq[eq[A;B];D] = ␈↓λB␈↓α eq[␈↓λB␈↓α;x] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ∧Keq[car[(A . B)];car[cdr[(A . (B . C))]]] = ␈↓
f␈↓
␈↓ ↓H␈↓We␈α
should␈αdefine␈α
a␈αversion␈α
of␈α␈↓αeq␈↓,␈α
say␈α␈↓αeq␈↓βTr␈↓,␈α
which␈αis␈α
defined␈αover␈α
␈↓ Tr␈↓␈αand␈α
acts␈αlike␈α
␈↓αeq␈↓;␈α
rather,␈αwe
␈↓ ↓H␈↓will simply extend the definition of ␈↓αeq␈↓ to ␈↓ S␈↓β1␈↓ so that it may compare two elements of ␈↓ Tr␈↓.
␈↓ ↓H␈↓α␈↓ ∧veq[␈↓
t␈↓α;␈↓
t␈↓α] = ␈↓
t␈↓α eq[␈↓
f␈↓α;␈↓λB␈↓α] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ¬βeq[␈↓
f␈↓α;␈↓
f␈↓α] = ␈↓
t␈↓α eq[␈↓
t␈↓α;␈↓
f␈↓α] = ␈↓
f␈↓α
␈↓ ↓H␈↓α␈↓ εεeq[A;␈↓
t␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓We␈αneed␈αto␈αinclude␈α
a␈αconstruct␈αin␈αour␈α
language␈αto␈αeffect␈αa␈α
test-and-branch␈αoperation.␈α In␈αLISP␈α
this
␈↓ ↓H␈↓operation is indicated by the ␈↓↓conditional expression␈↓. It is written:
␈↓ ↓H␈↓α␈↓ ¬
[p␈↓β1␈↓α → e␈↓β1␈↓α; p␈↓β2␈↓α → e␈↓β2␈↓α; ... ; p␈↓βn␈↓α → e␈↓βn␈↓α]
␈↓ ↓H␈↓Each␈α␈↓αp␈↓βi␈↓␈αis␈αan␈αexpression␈αwhich␈αtakes␈αon␈αvalues␈αin␈αthe␈αset␈α␈↓ Tr␈↓␈αor␈αgives␈α␈↓λB␈↓;␈αeach␈α␈↓αe␈↓βi␈↓␈αis␈αan␈αexpression
␈↓ ↓H␈↓␈↓↓20 Symbolic expressions␈↓ 61.5␈↓
␈↓ ↓H␈↓which␈αwill␈αgive␈αa␈αvalue␈αin␈α␈↓ S␈↓β1␈↓.␈αWe␈αwill␈αrestrict␈αthe␈αconditional␈αexpression␈αsuch␈αthat␈αall␈αthe␈α␈↓αe␈↓βi␈↓␈αmust
␈↓ ↓H␈↓have values in the ␈↓↓same␈↓ domain or be ␈↓λB␈↓; i.e. all be in ␈↓<sexpr>␈↓ or all be in ␈↓ Tr␈↓.
␈↓ ↓H␈↓Assuming␈αthat␈α
an␈αinstance␈αof␈α
a␈αconditional␈αexpression␈α
meets␈αthis␈αrestriction,␈α
the␈αrule␈αfor␈α
evaluation
␈↓ ↓H␈↓is given by the following:
␈↓ ↓H␈↓␈↓ αhWe␈αevaluate␈αthe␈α␈↓αp␈↓βi␈↓'s␈αfrom␈αleft␈αto␈αright,␈αfinding␈αthe␈α␈↓↓first␈↓␈αwhich␈αreturns␈αvalue␈α␈↓
t␈↓.␈α When
␈↓ ↓H␈↓␈↓ αhwe␈α⊂find␈α∂such␈α⊂a␈α∂␈↓αp␈↓βi␈↓,␈α⊂we␈α∂evaluate␈α⊂the␈α∂corresponding␈α⊂␈↓αe␈↓βi␈↓.␈α∂ The␈α⊂value␈α∂of␈α⊂the␈α∂conditional
␈↓ ↓H␈↓␈↓ αhexpression␈α∞is␈α∂the␈α∞value␈α∂computed␈α∞by␈α∂that␈α∞␈↓αe␈↓βi␈↓;␈α∂if␈α∞all␈α∂of␈α∞the␈α∂␈↓αp␈↓βi␈↓'s␈α∞evaluate␈α∂to␈α∞␈↓
f␈↓␈α∂then␈α∞the
␈↓ ↓H␈↓␈↓ αhconditional␈α∞expression␈α∞gives␈α∞␈↓λB␈↓.␈α
The␈α∞conditional␈α∞expression␈α∞also␈α
gives␈α∞␈↓λB␈↓␈α∞if␈α∞we␈α
come
␈↓ ↓H␈↓␈↓ αhacross a ␈↓αp␈↓βi␈↓ which has value ␈↓λB␈↓ before we hit a ␈↓αp␈↓βi␈↓ with value ␈↓
t␈↓.
␈↓ ↓H␈↓Examples:
␈↓ ↓H␈↓α␈↓ ∧X[atom [A] → B; eq [A;(A . B)] → C] = B
␈↓ ↓H␈↓α␈↓ ∧V[eq [A;(A . B)] → C; atom [A] → B] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ αo[atom [(A . B)] → B; eq [A ; B] → C; eq [car[(A . B)]; cdr[(B . A)]] → E] = E
␈↓ ↓H␈↓α␈↓ ¬α[eq [A; A] → ␈↓
t␈↓α; atom [A] → ␈↓
f␈↓α] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ∧w[eq [A; A] → ␈↓
t␈↓α; atom [A] → B] = ␈↓λB␈↓α
␈↓ ↓H␈↓Notice␈αthat␈αthe␈αp␈↓β2␈↓␈αexpression␈α
of␈αthe␈αfirst␈αexample␈αis␈α
undefined,␈αbut␈αthe␈αconditional␈αgives␈α
value␈α␈↓αB␈↓
␈↓ ↓H␈↓since␈α∞p␈↓β1␈↓␈α∞gives␈α∞value␈α∞␈↓
t␈↓;␈α∞this␈α∂means␈α∞that␈α∞conditional␈α∞expressions␈α∞are␈α∞non-strict.␈α∞Note␈α∂however␈α∞that
␈↓ ↓H␈↓non-strictness␈αis␈αrelative␈α
to␈αa␈αsingle␈α
domain;␈αthus␈αthe␈α
last␈αexample␈αabove␈α
gives␈α␈↓λB␈↓␈αsince␈α
it␈αcontains
␈↓ ↓H␈↓␈↓αe␈↓βi␈↓'s of differing domains.
␈↓ ↓H␈↓Frequently␈αit␈αis␈αconvenient␈αto␈α
use␈αa␈αspecial␈αform␈αof␈αthe␈α
conditional␈αexpression␈αwhere␈αthe␈αfinal␈α␈↓αp␈↓βn␈↓␈α
is
␈↓ ↓H␈↓guaranteed␈αto␈αbe␈αtrue.␈αThere␈αare␈αmany␈αexpressions␈α
which␈αalways␈αevaluate␈αto␈α␈↓
t␈↓;␈α ␈↓αeq[1;1]␈↓␈αis␈αone.␈α
The
␈↓ ↓H␈↓simplest expression is the constant ␈↓
t␈↓.
␈↓ ↓H␈↓Consider the special form:␈↓ ¬Q␈↓α[p␈↓β1␈↓α → e␈↓β1␈↓α; ...; ␈↓
t␈↓α → e␈↓βn␈↓α]
␈↓ ↓H␈↓Now␈αif␈α
we␈αknow␈α
that␈αthe␈α
previous␈α␈↓αp␈↓βi␈↓'s␈αare␈α
either␈αtrue␈α
or␈αfalse␈↓π 20␈↓,␈α
the␈αfinal␈α
␈↓αp␈↓βn␈↓ → ␈↓αe␈↓βn␈↓-case␈αis␈αa␈α
catch-all
␈↓ ↓H␈↓or␈αotherwise-case␈αwhich␈αwill␈αbe␈αexecuted␈αif␈αnone␈αof␈α
the␈αprevious␈α␈↓αp␈↓βi␈↓'s␈αgive␈α␈↓
t␈↓.␈α Thus␈αthe␈αuse␈αof␈α
␈↓
t␈↓␈αin
␈↓ ↓H␈↓this context can be read "otherwise"; and the conditional can be read:
␈↓ ↓H␈↓␈↓ βN"If ␈↓αp␈↓β1␈↓ is true then ␈↓αe␈↓β1␈↓, else if ␈↓αp␈↓β2␈↓ is true then ..., otherwise ␈↓αe␈↓βn␈↓."
␈↓ ↓H␈↓The␈α∩introduction␈α∩of␈α∪conditional␈α∩expressions␈α∩has␈α∩further␈α∪widened␈α∩the␈α∩gap␈α∪between␈α∩traditional
␈↓ ↓H␈↓mathematical␈αtheories␈αand␈αcomputational␈αtheories.␈αPreviously␈αwe␈αcould␈αalmost␈αside-step␈αthe␈αissue␈α
of
␈↓ ↓H␈↓order␈αof␈α
evaluation;␈αit␈α
didn't␈αreally␈α
matter␈αunless␈α␈↓λB␈↓␈α
was␈αinvolved.␈α
But␈αnow␈α
the␈αvery␈α
definition␈αof
␈↓ ↓H␈↓meaning of conditionals involves an order of evaluation.
␈↓ ↓H␈↓The␈α
order␈α
of␈α
evaluation␈αis␈α
important␈α
from␈α
a␈αcomputational␈α
viewpoint:␈α
if␈α
we␈αare␈α
going␈α
to␈α
give␈αas
␈↓ ↓H␈↓value␈αthe␈αleftmost␈α␈↓αe␈↓βi␈↓␈αwhose␈α␈↓αp␈↓βi␈↓␈αevaluates␈αto␈α␈↓
t␈↓,␈αthen␈αthere␈αis␈αno␈αneed␈αto␈αcompute␈αany␈αof␈αthe␈αother␈α␈↓αe␈↓βj␈↓'s;
␈↓ ↓H␈↓those␈αvalues␈α
will␈αnever␈α
be␈αused.␈α
A␈αmore␈α
pressing␈αdifficulty␈α
is␈αthat␈α
of␈αpartial␈α
functions.␈αIf␈α
we␈αdid
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 20␈↓ and we know that all the ␈↓αe␈↓βi␈↓'s are elements of the same domain.
␈↓ ↓H␈↓␈↓↓1.5␈↓ εsPredicates and Conditional Expressions 21␈↓
␈↓ ↓H␈↓not␈α
impose␈α
an␈α
order␈α
of␈αevaluation␈α
on␈α
the␈α
components␈α
of␈αa␈α
conditional,␈α
then␈α
frequently␈α
we␈αwould
␈↓ ↓H␈↓attempt␈α⊃to␈α⊂evaluate␈α⊃expressions␈α⊃which␈α⊂would␈α⊃lead␈α⊂to␈α⊃undefined␈α⊃results:␈α⊂␈↓α[eq[0;0] → 1; ␈↓
t␈↓α → car[A]]␈↓
␈↓ ↓H␈↓gives␈α␈↓α1␈↓␈αusing␈α
the␈αmeaning␈αof␈αconditionals,␈α
whereas␈αthe␈αexpression␈αwould␈α
be␈αundefined␈αif␈α
we␈αwere
␈↓ ↓H␈↓required␈αto␈αevaluate␈α␈↓αcar[A]␈↓.␈αIf␈αwe␈αthink␈αof␈αan␈αoccurrence␈αof␈α␈↓λB␈↓␈αbeing␈αmapped␈αto␈αan␈αerror␈αmessage,
␈↓ ↓H␈↓evaluating␈α
␈↓αcar[A]␈↓␈αwould␈α
cause␈α
termination␈αof␈α
the␈αcomputation.␈α
But,␈α
if␈αwe␈α
continue␈αto␈α
allow␈α
␈↓λB␈↓␈αas
␈↓ ↓H␈↓an␈α∪argument␈α∪or␈α∪value,␈α∪then␈α∩we␈α∪can␈α∪characterize␈α∪the␈α∪effect␈α∩of␈α∪a␈α∪conditional␈α∪expression␈α∪as␈α∩a
␈↓ ↓H␈↓␈↓↓non-strict␈↓␈α
function.␈α
Recall,␈α
a␈α
non-strict␈αfunction␈α
is␈α
allowed␈α
to␈α
return␈αa␈α
value␈α
other␈α
than␈α
␈↓λB␈↓␈αwhen
␈↓ ↓H␈↓one␈α∞of␈α∞its␈α∂arguments␈α∞is␈α∞␈↓λB␈↓;␈α∞or,␈α∂put␈α∞another␈α∞way,␈α∞we␈α∂don't␈α∞examine␈α∞the␈α∞definedness␈α∂of␈α∞arguments
␈↓ ↓H␈↓before applying the function.
␈↓ ↓H␈↓For␈α∂example,␈α⊂let␈α∂␈↓αif(x;y;z)␈↓␈α∂be␈α⊂the␈α∂␈↓↓conditional␈α⊂function␈↓␈α∂␈↓π 21␈↓␈α∂computed␈α⊂by:␈α∂␈↓α[x → y; ␈↓
t␈↓α → z]␈↓.␈α⊂ We␈α∂can
␈↓ ↓H␈↓define ␈↓αif␈↓ as a non-strict function such that:
␈↓ ↓H␈↓␈↓ βx␈↓ ¬h␈↓αy␈↓ if ␈↓αx␈↓ is ␈↓
t␈↓
␈↓ ↓H␈↓␈↓ βx␈↓αif(x;y;z) =␈↓ ¬hz␈↓ if ␈↓αx␈↓ is ␈↓
f␈↓
␈↓ ↓H␈↓␈↓ βx␈↓ ¬h␈↓λB␈↓ if ␈↓αx␈↓ is ␈↓λB␈↓
␈↓ ↓H␈↓However␈αthere␈αis␈αmore␈αto␈αthe␈α"strictness"␈αimplied␈αby␈αconditional␈αexpressions␈αthan␈αjust␈αmaking␈αsure
␈↓ ↓H␈↓that proper arguments are passed on function calls.
␈↓ ↓H␈↓Consider the following algorithm:
␈↓ ↓H␈↓α␈↓ ∧{one[x] <= [x=0 → 1; ␈↓
t␈↓α → one[x-1]]
␈↓ ↓H␈↓Assume␈αthat␈α␈↓αone␈↓␈αis␈αnon-strict␈αand␈αassume␈αthe␈αdomain␈αof␈αdiscourse␈αis␈αthe␈αintegers.␈α That␈αmeans,␈α␈↓αone␈↓
␈↓ ↓H␈↓will␈α⊂try␈α⊂to␈α⊃compute␈α⊂with␈α⊂␈↓↓any␈↓␈α⊂(integer)␈α⊃argument␈α⊂it␈α⊂is␈α⊂given.␈α⊃ The␈α⊂algorithm␈α⊂for␈α⊂␈↓αone␈↓␈α⊃defines␈α⊂a
␈↓ ↓H␈↓function␈α∞giving␈α∂␈↓α1␈↓␈α∞for␈α∂any␈α∞non-negative␈α∞integer␈α∂and␈α∞is␈α∂undefined␈α∞for␈α∞any␈α∂other␈α∞number.␈α∂From␈α∞a
␈↓ ↓H␈↓computational␈αpoint␈αof␈αview,␈αhowever,␈α␈↓αone[-1]␈↓␈αappears␈α"undefined"␈αin␈αa␈αdifferent␈αsense␈αfrom␈α␈↓αcar[A]␈↓
␈↓ ↓H␈↓being␈α
"undefined".␈α
The␈α
computation␈α
␈↓αone[-1]␈↓␈α
does␈α
not␈α
terminate␈α
and␈α
is␈α
said␈α
to␈α
␈↓↓diverge␈↓.␈α
For␈αa␈α
partial
␈↓ ↓H␈↓function␈α
like␈α
␈↓αcar␈↓,␈α
we␈αcan␈α
give␈α
an␈α
error␈αmessage␈α
whenever␈α
we␈α
attempt␈αto␈α
apply␈α
the␈α
function␈α
to␈αan
␈↓ ↓H␈↓atomic␈α⊃argument,␈α⊃but␈α⊂we␈α⊃cannot␈α⊃expect␈α⊃to␈α⊂include␈α⊃tests␈α⊃like␈α⊃"if␈α⊂the␈α⊃computation␈α⊃␈↓αf[a]␈↓␈α⊃does␈α⊂not
␈↓ ↓H␈↓terminate␈α
then␈α
give␈α
error␈α
No.␈α
15."␈↓π 22␈↓.␈α
From␈αthe␈α
purely␈α
functional␈α
point␈α
of␈α
view,␈α
␈↓αone␈↓␈α
still␈αdefines␈α
the
␈↓ ↓H␈↓partial␈αfunction␈αwhich␈αis␈α␈↓α1␈↓␈αfor␈αthe␈αnon-negative␈αintegers,␈αbut␈αcomputationally␈αthere's␈α
an␈αimportant
␈↓ ↓H␈↓distinction to be made.
␈↓ ↓H␈↓So␈α
we␈α∞see␈α
that␈α∞a␈α
computation␈α∞may␈α
be␈α∞"undefined"␈α
for␈α∞two␈α
reasons:␈α∞it␈α
involves␈α∞a␈α
non-terminating
␈↓ ↓H␈↓computation␈α
or␈αit␈α
involves␈α
applying␈αa␈α
partial␈α
function␈αto␈α
a␈αvalue␈α
not␈α
in␈αits␈α
domain␈↓π 23␈↓.␈α
Note␈αthat
␈↓ ↓H␈↓the␈αdistinction␈αbetween␈α"undefined"␈αand␈α"diverges"␈αis␈αfuzzy.␈αIf␈αwe␈αrestrict␈αthe␈αdomain␈αof␈α␈↓αone␈↓␈αto␈αthe
␈↓ ↓H␈↓natural␈α∂numbers,␈α∂then␈α∂␈↓αone[-1]␈↓␈α∂denotes␈α∂␈↓λB␈↓␈α∞rather␈α∂than␈α∂diverges.␈α∂Or,␈α∂put␈α∂another␈α∂way,␈α∞"undefined
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 21␈↓␈αNotice␈αwe␈αare␈αwriting␈α`(...)'␈αrather␈αthan␈α`[...]'␈αsince␈αwe␈αare␈αtalking␈αabout␈αthe␈αfunction␈αand␈αnot␈αthe
␈↓ ↓H␈↓algorithm. See page 12.
␈↓ ↓H␈↓␈↓π 22␈↓␈α
A␈α
discussion␈α
of␈α
such␈α
topics␈α∞involves␈α
a␈α
description␈α
of␈α
the␈α
"halting␈α
problem"␈α∞for␈α
computational
␈↓ ↓H␈↓devices. See [Rog 67] for details.
␈↓ ↓H␈↓␈↓π 23␈↓ Compare ␈↓εw␈↓-undefined and E-undefined in [Mor 68].
␈↓ ↓H␈↓␈↓↓22 Symbolic expressions␈↓ 61.5␈↓
␈↓ ↓H␈↓strictness"␈α
is␈α
a␈α
special␈α
case␈α
of␈α
"divergent␈α
strictness"␈α
where␈α
we␈α
are␈α
able␈α
to␈α
predict␈αwhich␈α
computations
␈↓ ↓H␈↓will␈αnot␈αterminate.␈αThose␈αcases␈αcan␈αbe␈αchecked␈αby␈αdefining␈αthe␈αfunction␈αto␈αbe␈αstrict␈αover␈αa␈αdomain
␈↓ ↓H␈↓which␈αrules␈αout␈αthose␈αanomalies.␈α Thus␈αa␈αcase␈αcan␈αbe␈αmade␈αfor␈αidentifying␈αdivergent␈αcomputations
␈↓ ↓H␈↓with ␈↓λB␈↓; however there is typically more to non-termination that just "wrong kind of arguments".
␈↓ ↓H␈↓We␈α
want␈α
to␈α
extend␈α∞our␈α
discussion␈α
of␈α
strictness␈α
to␈α∞encompass␈α
divergence.␈α
Recall␈α
the␈α∞discussion␈α
on
␈↓ ↓H␈↓page 15␈α
of␈α␈↓αsecond[x; y] <= y␈↓.␈α
Defining␈α␈↓αsecond␈↓␈α
to␈αbe␈α
strict␈αrequired␈α
that␈αeach␈α
application␈α
of␈α␈↓αsecond␈↓
␈↓ ↓H␈↓determine␈α⊂whether␈α⊃either␈α⊂argument␈α⊃denoted␈α⊂␈↓λB␈↓.␈α⊂ If␈α⊃we␈α⊂want␈α⊃␈↓αsecond␈↓␈α⊂to␈α⊂be␈α⊃strict␈α⊂with␈α⊃respect␈α⊂to
␈↓ ↓H␈↓divergence,␈α
then␈αwe␈α
must␈α
test␈αeach␈α
argument␈α
for␈αdivergence.␈α
That␈α
implies␈αevaluation␈α
of␈α
each␈αof␈α
the
␈↓ ↓H␈↓arguments,␈α∪which␈α∀in␈α∪turn␈α∀implies␈α∪that␈α∀if␈α∪a␈α∪computation␈α∀of␈α∪an␈α∀argument␈α∪diverges,␈α∀then␈α∪the
␈↓ ↓H␈↓computation␈α⊃of␈α⊃the␈α⊃function␈α∩application␈α⊃must␈α⊃also␈α⊃diverge.␈α⊃ This␈α∩implies␈α⊃that␈α⊃it␈α⊃is␈α∩natural␈α⊃to
␈↓ ↓H␈↓associate␈α∪"strict␈α∪with␈α∪respect␈α∀to␈α∪divergence"␈α∪with␈α∪␈↓ CBV␈↓,␈α∪since␈α∀in␈α∪the␈α∪process␈α∪of␈α∀checking␈α∪for
␈↓ ↓H␈↓termination,␈α⊂we␈α⊂must␈α⊃compute␈α⊂values.␈α⊂However␈α⊃if␈α⊂a␈α⊂function␈α⊂is␈α⊃strict␈α⊂then␈α⊂calling␈α⊃style␈α⊂doesn't
␈↓ ↓H␈↓matter.
␈↓ ↓H␈↓In␈α∀contrast,␈α∀a␈α∀non-strict␈α∀function␈α∀does␈α∃not␈α∀check␈α∀arguments␈α∀for␈α∀divergence,␈α∀and␈α∃indeed␈α∀the
␈↓ ↓H␈↓divergence␈α∃of␈α∀a␈α∃computation␈α∀may␈α∃depend␈α∀on␈α∃the␈α∀calling␈α∃style.␈α∀ Consider␈α∃the␈α∃evaluation␈α∀of
␈↓ ↓H␈↓␈↓αsecond[one[-1]; B]␈↓␈α∂where␈α∂␈↓αone␈↓␈α∂is␈α∂total␈α∂over␈α∂the␈α∂integers.␈α∂This␈α∂evaluation␈α∂will␈α∂diverge␈α⊂under␈α∂␈↓ CBV␈↓
␈↓ ↓H␈↓while␈α
it␈α
converges␈αto␈α
␈↓αB␈↓␈α
using␈α␈↓ CBN␈↓.␈α
We␈α
cannot␈αrequire␈α
all␈α
our␈αfunctions␈α
to␈α
be␈αstrict␈α
if␈α
we␈αexpect␈α
to
␈↓ ↓H␈↓do␈α
any␈α
non-trivial␈α
computation.␈α That␈α
is,␈α
we␈α
need␈α
a␈αfunction␈α
which␈α
can␈α
determine␈α
its␈αvalue␈α
without
␈↓ ↓H␈↓computing␈αthe␈αvalues␈αof␈αall␈αof␈αits␈αarguments␈α--a␈α"don't␈αcare␈αcondition"--.␈α The␈αconditional␈αfunction
␈↓ ↓H␈↓is␈α
such␈α
a␈α
non-strict␈α
function.␈α
That␈α
is␈α␈↓αif(␈↓
t␈↓α;q;r)␈↓␈α
has␈α
value␈α
␈↓αq␈↓␈α
without␈α
knowing␈α
anything␈α
about␈αwhat
␈↓ ↓H␈↓happens␈αto␈α␈↓αr␈↓.␈α In␈αparticular,␈α␈↓αif(␈↓
t␈↓α;q;␈↓λB␈↓α) = q␈↓.␈α Likewise␈α␈↓αif(␈↓
f␈↓α;␈↓λB␈↓α;r) = r␈↓.␈α Now␈αsince␈α␈↓αif␈↓␈αis␈αto␈αbe␈αa␈αfunction
␈↓ ↓H␈↓and␈αtherefore␈α
single-valued,␈αif␈α
␈↓αif(␈↓
t␈↓α;q;␈↓λB␈↓α) = q␈↓␈αthen␈αfor␈α
any␈αargument␈α
␈↓αx␈↓,␈α␈↓αif(␈↓
t␈↓α;q;x) = q␈↓.␈α
Notice␈αthat␈α␈↓λB␈↓␈α
is
␈↓ ↓H␈↓now␈αcarrying␈α
an␈αadditional␈α"don't-care"␈α
interpretation;␈αthis␈αis␈α
consistent␈αwith␈αits␈α
previous␈αmeaning
␈↓ ↓H␈↓when we think of the function being computed by the algorithm.
␈↓ ↓H␈↓Even␈α
given␈α
that␈α
a␈αcomputational␈α
definition␈α
is␈α
desired,␈αthere␈α
are␈α
other␈α
plausible␈α
interpretations␈αof
␈↓ ↓H␈↓conditionals.␈α∀ Consider␈α∀the␈α∀definition:␈α∀␈↓αg[x;y] <= [lic[x] → 1;␈↓
t␈↓α → 1]␈↓.␈α∀Assuming␈α∀that␈α∀␈↓αlic␈↓␈α∀is␈α∃a␈α∀total
␈↓ ↓H␈↓predicate,␈αany␈αvalue␈αcomputed␈α
by␈α␈↓αg␈↓␈αwill␈αbe␈α␈↓α1␈↓.␈α
But␈αrequiring␈αleft-to-right␈αevaluation␈αcould␈α
spend␈αa
␈↓ ↓H␈↓great␈αdeal␈α
of␈αunnecessary␈αcomputation␈α
if␈α␈↓αlic␈↓␈αis␈α
a␈α␈↓αl␈↓ong␈α␈↓αi␈↓nvolved␈α
␈↓αc␈↓alculation.␈α Questions␈αof␈α
evaluation
␈↓ ↓H␈↓are␈α→non-trivial.␈α→We␈α→will␈α→spend␈α→two␈α→chapters,␈α→Chapter 3␈α→and␈α→Chapter 4,␈α~discussing␈α→LISP
␈↓ ↓H␈↓evaluation and its possible alternatives.
␈↓ ↓H␈↓What␈α⊂benefits␈α⊂have␈α∂resulted␈α⊂from␈α⊂our␈α∂study␈α⊂of␈α⊂␈↓λB␈↓␈α∂and␈α⊂divergence?␈α⊂ We␈α∂should␈α⊂have␈α⊂a␈α∂clearer
␈↓ ↓H␈↓understanding␈αof␈αthe␈αdifference␈αbetween␈αfunction␈αand␈α
algorithm␈αand␈αa␈αbetter␈αgrasp␈αof␈αthe␈αkinds␈α
of
␈↓ ↓H␈↓difficulties␈α
which␈α
can␈α
befall␈α
a␈α
computation.␈α
We␈α
have␈α
uncovered␈α
an␈α
important␈α
class␈α
of␈αdetectable
␈↓ ↓H␈↓errors.␈α The␈αcharacter␈αof␈αthese␈αmiscreants␈αis␈αthat␈αthey␈αoccur␈αin␈αthe␈αcontext␈αof␈αsupplying␈αthe␈αwrong
␈↓ ↓H␈↓␈↓↓kind␈↓␈α
of␈α
argument␈α
to␈α
a␈α
function.␈α
This␈α
kind␈α
of␈α
error␈α
is␈α
called␈α
a␈α
␈↓↓type␈α
fault␈↓,␈α
meaning␈α
that␈α
we␈α
expected
␈↓ ↓H␈↓an␈αargument␈α
of␈αa␈α
specific␈αtype,␈α
that␈αis␈α
from␈αa␈α
specific␈αdomain,␈α
and␈αsince␈α
it␈αwas␈α
not␈αforthcoming,␈α
we
␈↓ ↓H␈↓refuse␈α∂to␈α∞perform␈α∂any␈α∂kind␈α∞of␈α∂calculation.␈α∂Thus␈α∞␈↓αatom[␈↓
f␈↓α]␈↓␈α∂and␈α∂␈↓αcons[␈↓
t␈↓α;A]␈↓␈α∞are␈α∂undefined␈α∂since␈α∞both
␈↓ ↓H␈↓expect␈αelements␈αof␈α␈↓ S␈↓␈αas␈αarguments.␈α Divergent␈αcomputations␈αare␈αequally␈αrepugnant␈αbut␈αthere␈αis␈αno
␈↓ ↓H␈↓general method for testing whether an arbitrary calculation will terminate.
␈↓ ↓H␈↓It␈α∩may␈α∩not␈α⊃seem␈α∩like␈α∩you␈α⊃can␈α∩do␈α∩much␈α⊃useful␈α∩computation␈α∩with␈α⊃such␈α∩a␈α∩limited␈α∩collection␈α⊃of
␈↓ ↓H␈↓␈↓↓1.5␈↓ εsPredicates and Conditional Expressions 23␈↓
␈↓ ↓H␈↓operations␈α⊂as␈α∂those␈α⊂proposed␈α⊂in␈α∂LISP.␈α⊂Things␈α⊂are␈α∂not␈α⊂quite␈α∂as␈α⊂trivial␈α⊂as␈α∂they␈α⊂might␈α⊂seem.␈α∂ In
␈↓ ↓H␈↓elementary␈αnumber␈αtheory␈αall␈αyou␈αhave␈αis␈αzero␈αand␈αsome␈αsimple␈αfunctions,␈αand␈αelementary␈αnumber
␈↓ ↓H␈↓theory␈α
is␈αfar␈α
from␈αelementary.␈α
Manipulation␈αof␈α
our␈αprimitives,␈α
with␈αcomposition,␈α
and␈αconditional
␈↓ ↓H␈↓expressions, coupled with techniques for definition can ␈↓↓also␈↓ become complicated.
␈↓ ↓H␈↓Let's␈α∩apply␈α∩the␈α∩LISP␈α∩constructs␈α∩which␈α∩we␈α⊃now␈α∩have,␈α∩and␈α∩define␈α∩a␈α∩new␈α∩LISP␈α∩function.␈α⊃ For
␈↓ ↓H␈↓example:␈αour␈αpredicate␈α␈↓αeq␈↓␈αis␈αdefined␈αonly␈αfor␈αatomic␈αarguments.␈α We␈αwould␈αlike␈αto␈αtest␈αfor␈αequality
␈↓ ↓H␈↓of␈α∞arbitrary␈α∂S-exprs.␈α∞ What␈α∂should␈α∞this␈α∂more␈α∞complex␈α∞equality␈α∂mean?␈α∞ By␈α∂equality␈α∞we␈α∂mean:␈α∞as
␈↓ ↓H␈↓trees,␈α∂the␈α∞S-exprs␈α∂have␈α∞the␈α∂same␈α∞branching␈α∂structure;␈α∞and␈α∂the␈α∞corresponding␈α∂terminal␈α∂nodes␈α∞are
␈↓ ↓H␈↓labeled by the same atoms. Thus, we would like to define a predicate, ␈↓αequal␈↓, such that:
␈↓ ↓H␈↓α␈↓ ¬0equal[(A . B);(A . B)] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ¬tequal[A;A] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ¬0equal[(A . B);(B . A)] = ␈↓
f␈↓α
␈↓ ↓H␈↓α␈↓ ∧mequal[(A . (B . C));(A . (B . C))] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ∧mequal[(A . (B . C));((A . B) . C)] = ␈↓
f␈↓α
␈↓ ↓H␈↓Here's an informal description of such a predicate named ␈↓αequal␈↓.
␈↓ ↓H␈↓1.␈α
If␈αboth␈α
arguments␈αare␈α
atomic␈αthen␈α
see␈αwhat␈α
␈↓αeq␈↓␈αsays␈α
about␈αthem.␈α
We␈αcan␈α
test␈αif␈α
they␈α
are␈αboth
␈↓ ↓H␈↓␈↓ αλatomic by using ␈↓αatom␈↓ and a conditional expression.
␈↓ ↓H␈↓2. If one is atomic and the other is not they can't be equal S-exprs.
␈↓ ↓H␈↓3.␈α∂ Otherwise␈α∂both␈α∞are␈α∂non-atomic␈α∂S-exprs.␈α∞ Both␈α∂have␈α∂two␈α∞sub-expressions.␈α∂ Look␈α∂at␈α∂both␈α∞first
␈↓ ↓H␈↓␈↓ α_subexpressions.␈α
If␈α
these␈α
sub-expressions␈α
are␈α
not␈α
equal␈α
then␈α
the␈α
original␈α∞expressions␈α
cannot
␈↓ ↓H␈↓␈↓ α_be␈αequal␈α
either.␈α If␈α
the␈αfirst␈α
subexpressions␈α␈↓↓are␈↓␈α
equal␈αthen␈α
the␈αquestion␈α
of␈αwhether␈α
or␈αnot␈α
the
␈↓ ↓H␈↓␈↓ α_original␈α
expressions␈α
are␈α
equal␈α
depends␈α
on␈αthe␈α
equality␈α
of␈α
the␈α
second␈α
subexpressions.␈α Thus
␈↓ ↓H␈↓␈↓ α_the following definition:
␈↓ ↓H␈↓α equal[x;y] <=␈↓ βx[atom[x] → [atom[y] → eq [x;y]; ␈↓
t␈↓α → ␈↓
f␈↓α];
␈↓ ↓H␈↓α␈↓ αh atom[y] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ αh equal [car[x];car[y]] → equal[cdr[x];cdr[y]];
␈↓ ↓H␈↓α␈↓ αh ␈↓
t␈↓α → ␈↓
f␈↓α]
␈↓ ↓H␈↓α␈↓Notice␈αthat␈αwe␈αuse␈αnested␈α
conditional␈αexpressions␈αin␈α␈↓αequal␈↓:␈αe␈↓β1␈↓␈α
is␈αitself␈αa␈αconditional.␈αAlso␈α
we␈αhave
␈↓ ↓H␈↓used predicates in the e␈↓βi␈↓ positions at e␈↓β3␈↓ and e␈↓β11␈↓; this is allowable since ␈↓αequal␈↓ is a predicate.
␈↓ ↓H␈↓Let's␈α∪show␈α∪that␈α∪␈↓αequal␈↓␈α∪does␈α∩perform␈α∪correctly␈α∪for␈α∪a␈α∪specific␈α∩example.␈α∪ This␈α∪will␈α∪also␈α∪show␈α∩a
␈↓ ↓H␈↓complicated␈α
evaluation␈α∞of␈α
a␈α∞conditional␈α
expression.␈α∞ We␈α
will␈α∞use␈α
the␈α∞call-by-value␈α
rules.␈α∞ We␈α
will
␈↓ ↓H␈↓perform␈α
the␈αevaluation␈α
by␈αsubstituting␈α
the␈α
evaluated␈αactual␈α
parameters␈αfor␈α
the␈α
formal␈αparameters
␈↓ ↓H␈↓in␈α⊂the␈α⊂body␈α⊂of␈α⊂the␈α⊂definition.␈α⊂Then␈α⊃we␈α⊂will␈α⊂simplify␈α⊂the␈α⊂resulting␈α⊂expression.␈α⊂This␈α⊂is␈α⊃␈↓↓not␈↓␈α⊂the
␈↓ ↓H␈↓method LISP uses to perform call-by value, but has the same effect.
␈↓ ↓H␈↓␈↓↓24 Symbolic expressions␈↓ 61.5␈↓
␈↓ ↓H␈↓αequal[(A . B);(A . C)] =␈↓ βx[atom[(A . B)] → [atom[(A . C)] → eq [(A . B);(A . C)]; ␈↓
t␈↓α → ␈↓
f␈↓α];
␈↓ ↓H␈↓α␈↓ βx atom[(A . C)] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ βx equal [car[(A . B)];car[(A . C)]] → equal[cdr[(A . B)];cdr[(A . C)]];
␈↓ ↓H␈↓α␈↓ βx ␈↓
t␈↓α → ␈↓
f␈↓α]
␈↓ ↓H␈↓We␈αfind␈αthat␈αp␈↓β1␈↓␈α(i.e., ␈↓αatom[(A . B)]␈↓ )␈αand␈αp␈↓β2␈↓␈α( ␈↓αatom[(A . C)]␈↓ )␈αwhen␈αevaluated␈α(in␈αorder)␈αgive␈α␈↓
f␈↓.␈α We
␈↓ ↓H␈↓must now evaluate p␈↓β3␈↓, which is: ␈↓αequal[car[(A . B)];car[(A . C)]]␈↓. This reduces to ␈↓αequal[A;A]␈↓, and:
␈↓ ↓H␈↓α␈↓ αX equal[A;A] =␈↓ ∧_[atom[A] → [atom[A] → eq[A;A]; ␈↓
t␈↓α → ␈↓
f␈↓α];
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧_ atom[A] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧_ equal [car[A];car[A]] → equal[cdr[A];cdr[A]];
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧_ ␈↓
t␈↓α → ␈↓
f␈↓α]
␈↓ ↓H␈↓This␈αconditional␈αexpression␈αwill␈αevaluate␈αto␈α␈↓
t␈↓.␈αSo␈αp␈↓β3␈↓␈αin␈αthe␈αoriginal␈αcall␈αof␈α␈↓αequal[(A . B);(A . C)]␈↓␈αis
␈↓ ↓H␈↓true␈α∃and␈α⊗we␈α∃must␈α⊗evaluate␈α∃the␈α⊗e␈↓β3␈↓␈α∃expression␈α⊗which␈α∃is␈α⊗␈↓αequal[cdr[(A . B)];cdr[(A . C)]]␈↓.␈α∃That
␈↓ ↓H␈↓expression␈α∞simplifies␈α∞to␈α
␈↓αequal[B;C]␈↓␈α∞and␈α∞we␈α
call␈α∞␈↓αequal␈↓.␈α∞ After␈α
substitution␈α∞and␈α∞simplification␈α
␈↓αequal␈↓
␈↓ ↓H␈↓will finally return value ␈↓
f␈↓. That means that ␈↓αequal[(A . B);(A . C)]␈↓ gives ␈↓
f␈↓.
␈↓ ↓H␈↓Clearly,␈αevaluation␈αof␈αLISP␈αexpressions␈αin␈αthis␈αamount␈αof␈αdetail␈αis␈αnot␈αa␈αprocess␈αwhich␈αwe␈αwish␈αto
␈↓ ↓H␈↓do␈αvery␈αoften.␈αIt␈αmight␈αbe␈αsurmised␈αthat␈αsuch␈αa␈αprocess␈αis␈αa␈αcandidate␈αfor␈αexecution␈αby␈αa␈αmachine.
␈↓ ↓H␈↓Notice␈αthat␈α␈↓αeq[(A . B);(A . C)]␈↓␈αappeared␈αbut␈αwas␈αnever␈αevaluated␈αbecause␈αof␈αleft-to-right␈αevaluation
␈↓ ↓H␈↓scheme of conditional expressions.
␈↓ ↓H␈↓Finally, to include conditional expressions in our syntax of LISP expressions, we should add:
␈↓ ↓H␈↓<form>␈↓ αh::= <conditional expression>
␈↓ ↓H␈↓<conditional expression>␈↓ ∧X::= [<form> → <form>; ...; <form> → <form>] (see page 17)
␈↓ ↓H␈↓These␈α⊂syntax␈α∂equations␈α⊂fail␈α∂to␈α⊂capture␈α⊂all␈α∂of␈α⊂our␈α∂intended␈α⊂meaning.␈α∂For␈α⊂example,␈α⊂the␈α∂<form>s
␈↓ ↓H␈↓appearing␈αin␈α
the␈αp␈↓βi␈↓-position␈αare␈α
restricted␈αto␈αbe␈α
forms␈αtaking␈α
values␈αin␈α␈↓ Tr␈↓,␈α
the␈αtruth␈αdomain.␈α
That
␈↓ ↓H␈↓restriction␈α∞is␈α∞not␈α∞expressed␈α∞in␈α
the␈α∞equations,␈α∞and␈α∞indeed,␈α∞is␈α
difficult␈α∞to␈α∞express␈α∞naturally␈α∞in␈α
such
␈↓ ↓H␈↓syntax equations. See [Hop 69] for a discussion of expressibility and grammars.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I Evaluate the following:
␈↓ ↓H␈↓␈↓ βR␈↓↓1.␈↓α eq[X;Y] ␈↓↓2.␈↓α cons[X;Y] ␈↓↓3.␈↓α car[(X . Y)] ␈↓↓4.␈↓α car[cons[X;Y]]
␈↓ ↓H␈↓α␈↓↓5.␈↓α cadr[(X .(Y . NIL))]␈↓ ε8␈↓↓6.␈↓α cdar[(X .(Y . NIL))]
␈↓ ↓H␈↓α␈↓↓7.␈↓α eq[cdr[(A . B)];cdr[(C . B)]]␈↓ ε8␈↓↓8.␈↓α atom[cons[(A . B);(C . D)]]
␈↓ ↓H␈↓␈↓↓1.5␈↓ εsPredicates and Conditional Expressions 25␈↓
␈↓ ↓H␈↓α␈↓↓9.␈↓α cons[atom[A];atom[(A . B)]]␈↓ ε8␈↓↓10.␈↓α eq[atom[ATOM];atom[EQ]]
␈↓ ↓H␈↓α␈↓ βk␈↓↓11.␈↓α [␈↓
t␈↓α → A; ␈↓
t␈↓α → B] ␈↓↓12.␈↓α [␈↓
f␈↓α → A; ␈↓
t␈↓α → B] ␈↓↓13.␈↓α [eq[A;B] → 4]
␈↓ ↓H␈↓α␈↓↓14.␈↓α [atom[X] → atom[X]; ␈↓
t␈↓α → FOO]␈↓ ε8␈↓↓15.␈↓α [eq[EQ; X] → A; eq[A; B] → B; ␈↓
t␈↓α → C]
␈↓ ↓H␈↓α␈↓ βJ␈↓↓16.␈↓α cons[[eq[A; B] → 1; ␈↓
t␈↓α → FOO]; cons[A; cadr[(A . (B . C))]]]
␈↓ ↓H␈↓α␈↓↓17.␈↓α equal[(A . B);(A . B)]␈↓ ε8␈↓↓18.␈↓α eq[(A . B);(A . B)]
␈↓ ↓H␈↓II Consider the following definition:
␈↓ ↓H␈↓α␈↓ αX twist[s] <=␈↓ ∧λ[atom[s] → s;
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧λ ␈↓
t␈↓α → cons[twist[cdr[s]];twist[car[s]]]]
␈↓ ↓H␈↓α␈↓↓1␈↓. Is the function partial or is it total? Now evaluate:
␈↓ ↓H␈↓␈↓↓2.␈↓α twist[A] ␈↓↓3.␈↓α twist[(A . B)] ␈↓↓4.␈↓α twist[((A . B) . C)]
␈↓ ↓H␈↓III Now try:
␈↓ ↓H␈↓α␈↓ αXfindem[x;y] <=␈↓ ∧([atom[x] → [eq[x;y] → T; ␈↓
t␈↓α → NIL];
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧( ␈↓
t␈↓α → cons[findem[car[x];y];findem[cdr[x];y]]]
␈↓ ↓H␈↓α␈↓↓1␈↓. Is this function total? Now evaluate:
␈↓ ↓H␈↓␈↓ α⎇␈↓↓2.␈↓α findem[(A . B);A] ␈↓↓3.␈↓α findem[(B .(A . C));A] ␈↓↓4.␈↓α findem[(B .(A . C));C]
␈↓ ↓H␈↓α␈↓ ¬-␈↓↓5.␈↓α findem[(A . B);(A . B)]
␈↓ ↓H␈↓␈↓ ∧C␈↓↓1.6 Sequences: Abstract Data Structures␈↓
␈↓ ↓H␈↓In␈α
several␈α
areas␈α
of␈α
mathematics␈α
it␈α
is␈α
convenient␈α
to␈α
deal␈α
with␈α
sequences␈α
of␈α
information.␈α
For␈α
example,
␈↓ ↓H␈↓a␈αproblem␈αdomain␈αmay␈αbe␈αmore␈αnaturally␈αdescribed␈αas␈αordered␈αcollections␈αof␈αnumbers␈αrather␈αthan
␈↓ ↓H␈↓individual␈α∩numbers.␈α∩ This␈α∩may␈α∩either␈α∩simplify␈α∩understanding␈α∩of␈α∩the␈α∩problem␈α∩or␈α∩simplify␈α⊃the
␈↓ ↓H␈↓formulation␈α⊃of␈α⊃the␈α⊃functions␈α⊃defined␈α∩on␈α⊃the␈α⊃domain.␈α⊃ Several␈α⊃programming␈α∩languages␈α⊃include
␈↓ ↓H␈↓arrays␈α∞as␈α∞representations␈α∞of␈α∞these␈α∞mathematical␈α
ideas.␈α∞ We␈α∞should␈α∞notice␈α∞that␈α∞sequences␈α∞are␈α
data
␈↓ ↓H␈↓structures.␈αWe␈α
will␈αhave␈α
to␈αdescribe␈αconstructors,␈α
selectors,␈αand␈α
recognizers␈αfor␈α
them.␈αSubsequently
␈↓ ↓H␈↓we will explore applications of sequences as data structures.
␈↓ ↓H␈↓After␈αa␈α
certain␈αfamiliarity␈αis␈α
gained␈αin␈α
the␈αapplication␈αof␈α
algorithms␈αwhich␈α
manipulate␈αsequences,
␈↓ ↓H␈↓␈↓↓26 Symbolic expressions␈↓ 71.6␈↓
␈↓ ↓H␈↓we␈α
will␈α
discuss␈αthe␈α
problems␈α
of␈α
representation␈αand␈α
implementation␈α
of␈αthis␈α
data␈α
structure.␈α
We␈αwill
␈↓ ↓H␈↓first␈α∞give␈α
an␈α∞implementation␈α
of␈α∞sequences␈α
in␈α∞terms␈α
of␈α∞S-expressions.␈α
That␈α∞is,␈α
we␈α∞will␈α∞describe␈α
an
␈↓ ↓H␈↓␈↓λr␈↓-mapping␈αgiving␈αa␈αrepresentation␈αof␈αsequences␈αand␈αtheir␈αprimitive␈αoperations␈αin␈αterms␈αof␈αLISP's
␈↓ ↓H␈↓S-exprs␈α and␈α!primitive␈α functions.␈α Still␈α!later␈α in␈α Section 7.2␈α!we␈α will␈α!discuss␈α low-level
␈↓ ↓H␈↓implementation of this data structure in terms of conventional machines.
␈↓ ↓H␈↓But␈α⊂now␈α⊂we␈α∂will␈α⊂study␈α⊂sequences␈α⊂as␈α∂abstract␈α⊂data␈α⊂structures:␈α∂what␈α⊂are␈α⊂their␈α⊂essential␈α∂structural
␈↓ ↓H␈↓characteristics?␈α What␈αproperties␈αshould␈αbe␈αpresent␈αin␈αa␈αprogramming␈αlanguage␈αto␈αallow␈α
a␈αnatural
␈↓ ↓H␈↓and␈α∃flexible␈α∃representation?␈α∃ This␈α∃discussion␈α∃will␈α∃shed␈α∃light␈α∃on␈α∃the␈α∃important␈α∃problems␈α∃of
␈↓ ↓H␈↓representation and abstraction.
␈↓ ↓H␈↓A␈αsequence␈α
is␈αan␈αordered␈α
set␈αof␈αelements␈↓π 24␈↓.␈α
For␈αexample,␈α␈↓↓(x␈↓β1␈↓↓,␈α
x␈↓β2␈↓↓,␈αx␈↓β3␈↓↓)␈↓,␈αis␈α
standard␈αnotation␈α
for␈αa
␈↓ ↓H␈↓sequence␈α∂of␈α∂the␈α∂three␈α∂elements␈α∂␈↓↓x␈↓β1␈↓↓,␈α∂x␈↓β2␈↓,␈α∂and␈α⊂␈↓↓x␈↓β3␈↓.␈α∂ The␈α∂length␈α∂of␈α∂a␈α∂sequence␈α∂is␈α∂defined␈α∂to␈α⊂be␈α∂the
␈↓ ↓H␈↓number␈α∩of␈α∩elements␈α∩in␈α∩that␈α∩sequence.␈α∪ We␈α∩will␈α∩allow␈α∩sequences␈α∩to␈α∩have␈α∩sub-sequences␈α∪to␈α∩an
␈↓ ↓H␈↓arbitrary␈α⊃finite␈α⊃depth.␈α⊃ That␈α⊃is,␈α⊃the␈α⊃elements␈α⊃of␈α⊃a␈α⊃sequence␈α⊃will␈α⊃either␈α⊃be␈α⊃individuals␈α⊃or␈α⊂may
␈↓ ↓H␈↓themselves␈α
be␈α
sequences.␈α
For␈α
example,␈α
a␈α
sequence␈α
of␈α
length␈α
␈↓αn␈↓,␈α
each␈α
of␈α
whose␈α
elements␈α
are␈α
sequences
␈↓ ↓H␈↓of length ␈↓αm␈↓, is a matrix. Here are BNF equations for sequences and their elements:
␈↓ ↓H␈↓<seq>␈↓ β(::= ␈↓↓(␈↓ <seq elem>, ...,<seq elem> ␈↓↓)␈↓ ␈↓π 25␈↓
␈↓ ↓H␈↓<seq elem>␈↓ β(::= <indiv> | <seq>
␈↓ ↓H␈↓<indiv>␈↓ β(:: = <literal indiv> | <numeral> | -<numeral>
␈↓ ↓H␈↓<literal indiv>␈↓ β(:: = <indiv letter> | <literal indiv><indiv letter> | <literal indiv><digit>
␈↓ ↓H␈↓<numeral>␈↓ β(:: = <digit> | <numeral><digit>
␈↓ ↓H␈↓<indiv letter>␈↓ β(:: =␈↓↓ A | B | C ... | Z␈↓
␈↓ ↓H␈↓<digit>␈↓ β(:: = ␈↓↓0 | 1 | 2 ... | 9␈↓
␈↓ ↓H␈↓Notice␈αthat␈αthe␈α
structure␈αof␈α<indiv>␈α
is␈αthe␈αsame␈α
as␈αthat␈αfor␈α
LISP's␈α<atom>;␈αthe␈α
only␈αdifference␈αis␈α
in
␈↓ ↓H␈↓the␈α⊃fonts␈α⊃used␈α⊃for␈α⊃letters␈α⊃and␈α⊃digits.␈α⊂We␈α⊃have␈α⊃made␈α⊃the␈α⊃distinction␈α⊃between␈α⊃LISP␈α⊃atoms␈α⊂and
␈↓ ↓H␈↓sequence␈α
individuals␈α
intentionally.␈α
Thus␈α
␈↓↓(A, (B, C), D, (E, B))␈↓␈α∞is␈α
a␈α
sequence␈α
of␈α
length␈α∞four,␈α
whose
␈↓ ↓H␈↓second␈α∩and␈α∪fourth␈α∩elements␈α∪are␈α∩also␈α∩sequences.␈α∪ We␈α∩will␈α∪use␈α∩"␈↓↓( )␈↓"␈α∩as␈α∪notation␈α∩for␈α∪the␈α∩empty
␈↓ ↓H␈↓sequence.
␈↓ ↓H␈↓We␈α∞want␈α∞to␈α∂write␈α∞LISP-like␈α∞functions␈α∞operating␈α∂over␈α∞sequences,␈α∞so␈α∞we␈α∂will␈α∞at␈α∞least␈α∞need␈α∂to␈α∞give
␈↓ ↓H␈↓constructors,␈αselectors,␈αrecognizers,␈αand␈αpredicates␈αfor␈αsequences.␈α As␈αin␈αthe␈αcase␈αof␈αS-exprs,␈αwe␈αwill
␈↓ ↓H␈↓include the undefined element, and the full domain of sequences will be named
␈↓ ↓H␈↓␈↓ ¬M␈↓ Seq␈↓ = ␈↓<seq>␈↓∪{␈↓λB␈↓}.
␈↓ ↓H␈↓As on page 19, we extend the primitive LISP operations to include this new domain, by defining:
␈↓ ↓H␈↓␈↓ ¬b␈↓ S␈↓β2␈↓ = ␈↓ S␈↓β1␈↓∪␈↓<seq>␈↓,
␈↓ ↓H␈↓and extend each operation appropriately over ␈↓ S␈↓β2␈↓. For example:
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 24␈↓␈α∩For␈α∩an␈α∩alternative␈α∩description␈α∩of␈α∩sequences␈α∩and␈α∩a␈α∩discussion␈α∩of␈α∩a␈α∩different␈α∩view␈α∩of␈α⊃data
␈↓ ↓H␈↓structures see page 39.
␈↓ ↓H␈↓␈↓π 25␈↓ For the meaning of these ellipses see page 17.
␈↓ ↓H␈↓␈↓↓1.6␈↓ π#Sequences: Abstract Data Structures 27␈↓
␈↓ ↓H␈↓α␈↓ ¬}atom[␈↓↓A␈↓α] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ε car[␈↓↓A␈↓α] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ¬ocar[␈↓↓(A, B)␈↓α] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ¬pcons[␈↓↓A␈↓; ␈↓↓B␈↓α] = ␈↓λB␈↓α
␈↓ ↓H␈↓α␈↓ ¬missexpr[␈↓↓(A)␈↓α] = ␈↓
f␈↓α
␈↓ ↓H␈↓We␈α∂need␈α∂to␈α∂define␈α∞some␈α∂data␈α∂structure␈α∂operations␈α∂specific␈α∞to␈α∂sequences.␈α∂ What␈α∂are␈α∂the␈α∞essential
␈↓ ↓H␈↓characteristics␈α
of␈αa␈α
sequence?␈αFirst,␈α
a␈α
sequence␈αeither␈α
is␈αempty␈α
or␈α
has␈αelements.␈α
Thus␈αwe␈α
will␈αwant␈α
a
␈↓ ↓H␈↓predicate␈α∂to␈α∞test␈α∂for␈α∂emptyness.␈α∞ Next,␈α∂if␈α∂the␈α∞sequence␈α∂is␈α∞non-empty,␈α∂we␈α∂should␈α∞be␈α∂able␈α∂to␈α∞select
␈↓ ↓H␈↓elements. Finally, given some elements, we should be able to build a new sequence from them.
␈↓ ↓H␈↓The␈α⊂basic␈α∂predicate,␈α⊂which␈α∂tests␈α⊂for␈α∂emptyness,␈α⊂is␈α∂called␈α⊂␈↓αnull␈↓.␈α∂ Predicates␈α⊂on␈α∂sequences␈α⊂are␈α∂like
␈↓ ↓H␈↓predicates on S-expressions, mapping sequences to truth values in ␈↓ Tr␈↓␈↓π 26␈↓.
␈↓ ↓H␈↓␈↓ αX␈↓ βx␈↓
t␈↓ if ␈↓αx␈↓ is the empty sequence, ␈↓↓( )␈↓.
␈↓ ↓H␈↓␈↓ αX␈↓αnull[x]␈↓ is␈↓ βx␈↓
f␈↓ if ␈↓αx␈↓ is a non-empty sequence.
␈↓ ↓H␈↓␈↓ αX␈↓ βx␈↓λB␈↓ otherwise.
␈↓ ↓H␈↓␈↓ εε␈↓αnull[␈↓↓( )␈↓α] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ¬nnull[␈↓↓(A, B)␈↓α] = ␈↓
f␈↓α
␈↓ ↓H␈↓α␈↓ επnull[␈↓
f␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓Thus␈α
␈↓αnull␈↓␈α
gives␈α
usable␈α
values␈α
only␈α
for␈α
sequences.␈α
Since␈α
we␈α
intend␈α
to␈α
operate␈α
on␈α∞domains␈α
which
␈↓ ↓H␈↓contain␈αdata␈α
structures␈αother␈αthan␈α
sequences,␈αwe␈αwill␈α
need␈αa␈αrecognizer␈α
to␈αbe␈αsure␈α
that␈α␈↓αnull␈↓␈α
is␈αnot
␈↓ ↓H␈↓applied to arguments which are ␈↓↓not␈↓ sequences. We will name this recognizer ␈↓αisseq␈↓.
␈↓ ↓H␈↓␈↓ ¬Y␈↓αisseq[␈↓↓(A, B, C)␈↓α] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ ε¬isseq[␈↓↓A␈↓α] = ␈↓
f␈↓
␈↓ ↓H␈↓␈↓ ¬≡␈↓αisseq[A] = ␈↓
f␈↓ ␈↓αisseq[␈↓
t␈↓α] = ␈↓
f␈↓
␈↓ ↓H␈↓␈↓ ελ␈↓αisseq[␈↓↓()␈↓α] = ␈↓
t␈↓
␈↓ ↓H␈↓␈↓ ¬}␈↓αisseq[␈↓λB␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓The␈α∞predicate␈α
␈↓αisseq␈↓␈α∞is␈α
total␈α∞over␈α
all␈α∞domains,␈α∞whereas␈α
␈↓αnull␈↓␈α∞is␈α
only␈α∞partial:␈α
total␈α∞over␈α∞␈↓<seq>␈↓,␈α
but
␈↓ ↓H␈↓undefined for S-exprs.
␈↓ ↓H␈↓While␈α∂on␈α∂the␈α∂subject␈α∂of␈α⊂predicates,␈α∂there␈α∂are␈α∂a␈α∂couple␈α∂more␈α⊂we␈α∂shall␈α∂need.␈α∂ The␈α∂first␈α∂one␈α⊂is␈α∂a
␈↓ ↓H␈↓recognizer,␈α
␈↓αisindiv␈↓,␈αwhich␈α
will␈αgive␈α
value␈α␈↓
t␈↓␈α
if␈αits␈α
argument␈α
is␈αan␈α
individual,␈αgive␈α
␈↓
f␈↓␈αif␈α
its␈αargument␈α
is
␈↓ ↓H␈↓a sequence, and will give ␈↓λB␈↓ otherwise.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 26␈↓␈α
The␈α
reason␈αfor␈α
restructuring␈α
LISP␈α
predicates␈αmight␈α
now␈α
be␈α
apparent␈αto␈α
previous␈α
users␈αof␈α
LISP:
␈↓ ↓H␈↓if␈α
we␈αmapped␈α
the␈αtruth␈α
values␈αto␈α
the␈αatoms␈α
␈↓αT␈↓␈α
and␈α␈↓αNIL␈↓␈α
as␈αis␈α
typically␈αdone,␈α
then␈αwe'd␈α
have␈αto␈α
map
␈↓ ↓H␈↓truth␈αvalues␈αof␈αsequence-predicates␈αto␈αrepresentations␈αas␈αsequence␈αelements,␈αand␈αwe␈αwould␈αhave␈αto
␈↓ ↓H␈↓perpetuate that decision for every new abstract data structure domain that we wanted to introduce.
␈↓ ↓H␈↓␈↓↓28 Symbolic expressions␈↓ 71.6␈↓
␈↓ ↓H␈↓The␈αsecond␈αpredicate␈αis␈αthe␈αextension␈αof␈αthe␈αequality␈αrelation␈αto␈αthe␈αclass␈αof␈α
sequence␈αindividuals.
␈↓ ↓H␈↓We␈α
shall␈α∞use␈α
the␈α∞same␈α
name,␈α
␈↓αeq␈↓,␈α∞as␈α
we␈α∞did␈α
for␈α
the␈α∞S-expression␈α
predicate.␈α∞ In␈α
fact,␈α∞whenever␈α
we
␈↓ ↓H␈↓define␈α
a␈α
new␈αabstract␈α
data␈α
type␈αwe␈α
will␈α
assume␈α
that␈αan␈α
appropriate␈α
version␈αof␈α
␈↓αeq␈↓␈α
is␈α
available␈αfor
␈↓ ↓H␈↓the␈αelements␈α
of␈αthe␈αbase␈α
domain.␈αOne␈αof␈α
our␈αfirst␈αtasks␈α
will␈αbe␈αto␈α
extend␈αthat␈αequality␈α
relation␈αto
␈↓ ↓H␈↓the␈αwhole␈αdomain.␈αWe␈αwill␈αdo␈αso␈αfor␈αsequences␈αlater␈αin␈αthis␈αsection.␈αEquality␈αis␈αa␈αbasic␈αrelation␈αin
␈↓ ↓H␈↓mathematics␈α∂so␈α∂it␈α∂is␈α⊂not␈α∂surprising␈α∂to␈α∂see␈α∂it␈α⊂play␈α∂an␈α∂important␈α∂role␈α∂here.␈α⊂ ␈↓αeq␈↓␈α∂is␈α∂one␈α∂of␈α⊂the␈α∂few
␈↓ ↓H␈↓relations␈α⊃which␈α⊃we␈α⊃shall␈α⊃define␈α⊃across␈α⊃all␈α⊃domains.␈α⊃Functions␈α⊃or␈α⊃predicates␈α⊃like␈α⊃␈↓αeq␈↓,␈α∩which␈α⊃are
␈↓ ↓H␈↓applicable on several domains, are called ␈↓↓polymorphic functions␈↓.
␈↓ ↓H␈↓Next, the selectors for a (non-empty) sequence include: ␈↓αfirst␈↓, ␈↓αsecond␈↓, ... ,etc, where:
␈↓ ↓H␈↓␈↓ ¬U␈↓αfirst[␈↓↓(A, B, C)␈↓α] = ␈↓↓A␈↓α
␈↓ ↓H␈↓α␈↓ ¬Jsecond[␈↓↓(A, B, C)␈↓α] = ␈↓↓B␈↓α
␈↓ ↓H␈↓α␈↓ ¬cthird[␈↓↓(A, B)␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓It is also convenient to define an "all-but-first" selector, called ␈↓αrest␈↓.
␈↓ ↓H␈↓␈↓ ¬@␈↓αrest[␈↓↓(A, B, C)␈↓α] = ␈↓↓(B, C)␈↓α
␈↓ ↓H␈↓α␈↓ ¬drest[␈↓↓(B, C)␈↓α] = ␈↓↓(C)␈↓α
␈↓ ↓H␈↓α␈↓ εrest[␈↓↓(C)␈↓α] = ␈↓↓()␈↓α
␈↓ ↓H␈↓α␈↓ ε¬rest[␈↓↓C␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓␈↓ εα␈↓αrest[␈↓↓( )␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓In␈αconjunction␈α
with␈α␈↓αrest␈↓,␈α
we␈αshall␈α
utilize␈αa␈α
constructor,␈α␈↓αconcat␈↓,␈α
which␈αis␈α
to␈αadd␈α
a␈αsingle␈α
element␈αto
␈↓ ↓H␈↓the front of a sequence.
␈↓ ↓H␈↓␈↓ ¬&␈↓αconcat[␈↓↓A␈↓α;␈↓↓(B,C)␈↓α] = ␈↓↓(A, B, C)␈↓α
␈↓ ↓H␈↓α␈↓ ¬\concat[␈↓↓A␈↓α;␈↓↓( )␈↓α] = ␈↓↓(A)␈↓α
␈↓ ↓H␈↓α␈↓ ¬∃concat[␈↓↓(A)␈↓α;␈↓↓(B,C)␈↓α] = ␈↓↓((A), B, C)␈↓α
␈↓ ↓H␈↓α␈↓ ¬Rconcat[␈↓↓(B,C)␈↓α;␈↓↓A␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓␈↓ ¬c␈↓αconcat[␈↓↓A␈↓α; ␈↓↓B␈↓α] = ␈↓λB␈↓
␈↓ ↓H␈↓The␈αfinal␈αconstructor␈αis␈αcalled␈α␈↓αseq␈↓;␈αit␈αtakes␈αan␈αarbitrary␈αnumber␈αof␈αsequence␈αelements␈αas␈αarguments
␈↓ ↓H␈↓and␈α∩returns␈α∩a␈α∩sequence␈α⊃consisting␈α∩of␈α∩those␈α∩elements␈α∩(in␈α⊃the␈α∩obvious␈α∩order).␈α∩ Let␈α∩␈↓λα␈↓β1␈↓, ..., ␈↓λα␈↓βn␈↓␈α⊃be
␈↓ ↓H␈↓elements of <seq elem>, then:
␈↓ ↓H␈↓α␈↓ ¬
seq[␈↓λα␈↓β1␈↓α; ␈↓λα␈↓β2␈↓α; ...; ␈↓λα␈↓βn␈↓α] = ␈↓↓(␈↓λα␈↓β1␈↓↓, ..., ␈↓λα␈↓βn␈↓↓)␈↓
␈↓ ↓H␈↓One␈αquestion␈α
may␈αhave␈α
come␈αto␈α
mind:␈αhow␈α
do␈αwe␈α
know␈αwhen␈α
we␈αhave␈α
a␈αsufficient␈α
set␈αof␈α
functions
␈↓ ↓H␈↓for␈αthe␈αmanipulation␈αof␈αan␈αabstract␈αdata␈αstructure?␈α How␈αdo␈αwe␈αknow␈αwe␈αhaven't␈αleft␈αsome␈αcrucial
␈↓ ↓H␈↓functions␈αout?␈αIf␈αwe␈αhave␈αenough,␈αhow␈α
do␈αwe␈αknow␈αthat␈αwe␈αhaven't␈αincluded␈αtoo␈α
many?␈αActually,
␈↓ ↓H␈↓this␈αsecond␈αcase␈αisn't␈αdisastrous,␈αbut␈αwhen␈αimplementing␈αthe␈αfunctions␈αit␈αwould␈αbe␈αnice␈αto␈α
minimize
␈↓ ↓H␈↓the␈α
number␈α
of␈α
primitives␈α
we␈α
have␈α
to␈α
program.␈α These␈α
problems␈α
are␈α
worthy␈α
of␈α
study␈α
and␈α
are␈αthe
␈↓ ↓H␈↓concern␈α
of␈α
anyone␈α
interested␈α
in␈α
the␈α
design␈α
of␈α
programming␈α
languages.␈α
We␈α
will␈α
say␈α
a␈α
bit␈α
more␈α
about
␈↓ ↓H␈↓solutions to these questions beginning on page 35.
␈↓ ↓H␈↓␈↓↓1.6␈↓ π#Sequences: Abstract Data Structures 29␈↓
␈↓ ↓H␈↓Notice␈α⊂that␈α⊂we␈α⊃have␈α⊂been␈α⊂describing␈α⊃the␈α⊂sequence␈α⊂functions␈α⊃without␈α⊂regard␈α⊂to␈α⊃any␈α⊂underlying
␈↓ ↓H␈↓representation.␈α
We␈αhave␈α
said␈αnothing␈α
about␈αthese␈α
sequence␈αoperations␈α
except␈αthat␈α
they␈αconstruct,
␈↓ ↓H␈↓test,␈αor␈αselect.␈α What␈αwe␈αare␈αdoing␈αis␈αconsidering␈αsequences␈αas␈αabstract␈αdata␈αstructures,␈αsuitable␈αfor
␈↓ ↓H␈↓manipulation␈αby␈αLISP-like␈α
algorithms.␈αHow␈αsequences␈α
are␈αrepresented␈αas␈α
S-exprs␈αor␈αrepresented␈α
on
␈↓ ↓H␈↓a␈α⊃machine,␈α⊃is␈α∩irrelevant.␈α⊃Sequences␈α⊃have␈α∩certain␈α⊃inherent␈α⊃structural␈α∩properties␈α⊃and␈α⊃it␈α∩is␈α⊃those
␈↓ ↓H␈↓properties␈αwhich␈αwe␈αmust␈αunderstand␈α␈↓↓before␈↓␈αwe␈αbegin␈αthinking␈αabout␈αrepresentation.␈α In␈αthe␈αnext
␈↓ ↓H␈↓section␈α
we␈α
will␈α
show␈α
how␈α
to␈α
represent␈α
sequences␈α
as␈α
certain␈α
S-expressions␈α
and␈α
sequence␈α
operations␈α
as
␈↓ ↓H␈↓LISP operations on that representation.
␈↓ ↓H␈↓Let's␈αdevelop␈αsome␈αexpertise␈αin␈αmanipulating␈αsequences.␈α The␈αfirst␈αexample␈αwill␈αbe␈αan␈αextension␈αof
␈↓ ↓H␈↓the␈α⊃equality␈α⊂relation␈α⊃to␈α⊂sequences.␈α⊃We␈α⊂perpetuate␈α⊃the␈α⊂name␈α⊃␈↓αequal␈↓␈α⊂from␈α⊃S-exprs,␈α⊂and␈α⊃the␈α⊂basic
␈↓ ↓H␈↓structure␈α
of␈αthe␈α
definition␈α
will␈αparallel␈α
that␈αof␈α
its␈α
namesake;␈αbut␈α
the␈αcomponents␈α
of␈α
the␈αdefinition
␈↓ ↓H␈↓will␈αinvolve␈αsequence␈αoperations␈αrather␈αthan␈αS-expr␈α
operations.␈αIt␈αwill␈αbe␈αof␈αvalue␈αto␈α
compare␈αthe
␈↓ ↓H␈↓two predicates. The S-expr version is to be found on page 23.
␈↓ ↓H␈↓α equal[x;y] <=␈↓ βh[null[x] → [null[y] → ␈↓
t␈↓α; ␈↓
t␈↓α → ␈↓
f␈↓α];
␈↓ ↓H␈↓α␈↓ βh null[y] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ βh isindiv[x] → [isindiv[y] → eq[x;y]; ␈↓
t␈↓α → ␈↓
f␈↓α];
␈↓ ↓H␈↓α␈↓ βh isindiv[y] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ βh equal[first[x];first[y]] → equal[rest[x];rest[y]];
␈↓ ↓H␈↓α␈↓ βh ␈↓
t␈↓α → ␈↓
f␈↓α]
␈↓ ↓H␈↓This␈α␈↓αequal␈↓␈α
works␈αon␈α
sequences␈αand␈α
sequence␈αelements␈αas␈α
its␈αS-expr␈α
counterpart␈αworked␈α
on␈αdotted
␈↓ ↓H␈↓pairs and atoms.
␈↓ ↓H␈↓Next,␈αwe␈αwill␈αwrite␈αa␈αpredicate␈α␈↓αmember␈↓␈αof␈αtwo␈αarguments␈α␈↓αx␈↓␈αand␈α␈↓αy␈↓.␈α ␈↓αx␈↓␈αis␈αto␈αbe␈αan␈αindividual;␈α␈↓αy␈↓␈αis␈αto
␈↓ ↓H␈↓be␈αa␈αsequence;␈α␈↓αmember␈↓␈αis␈αto␈αreturn␈α␈↓
t␈↓␈αjust␈αin␈αthe␈αcase␈αthat␈α␈↓αx␈↓␈αis␈αan␈αelement␈αof␈αthe␈αsequence␈α␈↓αy␈↓.␈α What
␈↓ ↓H␈↓does␈α
this␈αspecification␈α
tell␈αus?␈α
The␈αpredicate␈α
is␈α
partial.␈αThe␈α
recursion␈αshould␈α
be␈αon␈α
the␈αstructure␈α
of
␈↓ ↓H␈↓␈↓αy␈↓;␈αand␈αtermination␈α(with␈αvalue␈α␈↓
f␈↓)␈αshould␈αoccur␈αif␈α␈↓αy␈↓␈αis␈αthe␈αempty␈αsequence.␈αIf␈α␈↓αy␈↓␈αis␈αnot␈αempty␈αthen␈αit
␈↓ ↓H␈↓has␈αa␈αfirst␈αelement␈α(call␈αit␈α␈↓αz␈↓);␈αcompare␈α␈↓αz␈↓␈αwith␈α␈↓αx␈↓.␈α If␈αthese␈αelements␈αare␈αidentical␈αthen␈α␈↓αmember␈↓␈αshould
␈↓ ↓H␈↓return ␈↓
t␈↓; otherwise see if ␈↓αx␈↓ occurs in the remainder of the sequence ␈↓αy␈↓.
␈↓ ↓H␈↓Notes:
␈↓ ↓H␈↓␈↓↓1.␈↓␈αWe␈α
cannot␈αuse␈α␈↓αeq␈↓␈α
directly␈αto␈α
check␈αequality␈αsince,␈α
though␈α␈↓αx␈↓␈α
is␈αan␈αindividual,␈α
there␈αis␈α
no␈αreason
␈↓ ↓H␈↓that␈αthe␈αelements␈αof␈α␈↓αy␈↓␈αneed␈αbe.␈α We␈αwill␈αintroduce␈αa␈αsubsidiary␈αpredicate␈α␈↓αsame␈↓␈αto␈αassure␈αthat␈α
␈↓αeq␈↓␈αis
␈↓ ↓H␈↓applied only to arguments of the correct type.
␈↓ ↓H␈↓␈↓↓2.␈↓␈αRecall␈αthat␈αwe␈αcan␈αget␈αthe␈αfirst␈αelement␈αof␈αa␈αsequence␈αwith␈α␈↓αfirst␈↓,␈αand␈αthe␈αrest␈αof␈αa␈αsequence␈αwith
␈↓ ↓H␈↓␈↓αrest␈↓.
␈↓ ↓H␈↓␈↓↓30 Symbolic expressions␈↓ 71.6␈↓
␈↓ ↓H␈↓So here's ␈↓αmember␈↓:
␈↓ ↓H␈↓α␈↓ β8member[x;y] <=␈↓ ¬λ[null[y] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ β8␈↓ ¬λ same[first[y];x] → ␈↓
t␈↓α;
␈↓ ↓H␈↓α␈↓ β8␈↓ ¬λ ␈↓
t␈↓α → member[x;rest[y]]]
␈↓ ↓H␈↓αsame[u;v] <= [isindiv[u] → eq[u;v]; ␈↓
t␈↓α → ␈↓
f␈↓α]
␈↓ ↓H␈↓Next is an arithmetic example to calculate the number of elements in a sequence.
␈↓ ↓H␈↓α␈↓ β{length[n] <= [null[n] → 0; ␈↓
t␈↓α → plus[1;length[rest[n]]]]
␈↓ ↓H␈↓␈↓ ∧F␈↓↓1.7 Lists: Representations of Sequences␈↓
␈↓ ↓H␈↓We␈αcan␈αnow␈αwrite␈αLISP-like␈αfunctions␈αdescribing␈αoperations␈αon␈αsequences;␈αthe␈αalgorithms␈αare␈α
clean
␈↓ ↓H␈↓and␈αunderstandable.␈α However,␈αif␈αwe␈αwish␈αto␈αrun␈αthese␈αprograms␈αin␈αa␈αLISP␈αenvironment,␈αthen␈αwe
␈↓ ↓H␈↓have␈αto␈αrepresent␈αthe␈αdata␈αstructures␈αand␈αthe␈αalgorithms␈αin␈αterms␈αunderstandable␈αto␈αLISP␈↓π 27␈↓.␈αThis
␈↓ ↓H␈↓is␈α∞the␈α∞problem␈α∞of␈α∞representation.␈α∞Granted,␈α∞we␈α∞could␈α∞have␈α∞overcome␈α∞the␈α∞problem␈α∞by␈α
representing
␈↓ ↓H␈↓sequences␈α∂directly␈α∂as␈α∂LISP␈α∂S-expressions␈α∂and␈α∞could␈α∂have␈α∂written␈α∂functions␈α∂in␈α∂LISP␈α∂which␈α∞used
␈↓ ↓H␈↓␈↓αcar-cdr␈↓-chains␈α∞to␈α
directly␈α∞manipulate␈α∞the␈α
representations.␈α∞ However,␈α
the␈α∞resulting␈α∞programs␈α
would
␈↓ ↓H␈↓be␈αmuch␈αmore␈αdifficult␈αto␈αread␈αand␈αdebug␈αand␈αunderstand.␈α More␈αimportant,␈αthe␈αprograms␈αwould
␈↓ ↓H␈↓be␈α∞explicitly␈α∞tied␈α∞to␈α∞a␈α∞specific␈α∞representation␈α∞of␈α
the␈α∞abstract␈α∞data␈α∞structure.␈α∞At␈α∞some␈α∞later␈α∞date␈α
it
␈↓ ↓H␈↓might␈α∞be␈α∞desired␈α∞to␈α
change␈α∞the␈α∞representation;␈α∞then␈α∞many␈α
programs␈α∞would␈α∞have␈α∞to␈α∞be␈α
rewritten.
␈↓ ↓H␈↓We␈α∩will␈α∩illustrate␈α∩these␈α∪difficulties␈α∩soon.␈α∩ In␈α∩Section 2.3␈α∪we␈α∩develop␈α∩a␈α∩complex␈α∪algorithm␈α∩for
␈↓ ↓H␈↓differentiation␈α%on␈α%a␈α%class␈α%of␈α$polynomials,␈α%moving␈α%from␈α%an␈α%unclear␈α%and␈α$highly
␈↓ ↓H␈↓representation-dependent formulation, to a clear, concise, representation-independent algorithm.
␈↓ ↓H␈↓Obviously␈α⊃we␈α⊃will␈α∩always␈α⊃have␈α⊃to␈α∩supply␈α⊃a␈α⊃representational␈α∩bridge␈α⊃between␈α⊃the␈α∩abstract␈α⊃data
␈↓ ↓H␈↓structures␈α∩and␈α∩algorithms,␈α∪and␈α∩their␈α∩concrete␈α∪counterparts.␈α∩ One␈α∩aspect␈α∪of␈α∩this␈α∩study␈α∪of␈α∩data
␈↓ ↓H␈↓structures␈α
is␈α
to␈α
understand␈α
what␈α∞is␈α
required␈α
to␈α
build␈α
this␈α∞bridge␈α
and␈α
how␈α
best␈α
to␈α∞represent␈α
these
␈↓ ↓H␈↓requirements in a programming language.
␈↓ ↓H␈↓The␈α⊂first␈α⊂decision␈α⊃to␈α⊂be␈α⊂made␈α⊃is␈α⊂how␈α⊂to␈α⊃represent␈α⊂the␈α⊂abstract␈α⊃data␈α⊂structure;␈α⊂how␈α⊃should␈α⊂we
␈↓ ↓H␈↓represent␈α∂sequences␈α∞as␈α∂S-expressions?␈α∂How␈α∞should␈α∂we␈α∂choose␈α∞representations␈α∂in␈α∂general?␈α∞Usually
␈↓ ↓H␈↓there␈α∞is␈α∞not␈α∂just␈α∞one␈α∞"best"␈α∂representation.␈α∞Some␈α∞obvious␈α∂considerations␈α∞involve␈α∞the␈α∂difficulty␈α∞of
␈↓ ↓H␈↓implementing␈α∂the␈α∞primitive␈α∂operations␈α∂(constructors,␈α∞selectors,␈α∂recognizers,␈α∞and␈α∂predicates)␈α∂on␈α∞the
␈↓ ↓H␈↓abstract␈αdata␈α
structure.␈αAlso␈α
we␈αmust␈αkeep␈α
in␈αmind␈α
the␈αkinds␈αof␈α
algorithms␈αwhich␈α
we␈αwish␈αto␈α
write;
␈↓ ↓H␈↓computation␈α∀takes␈α∀time,␈α∀and␈α∀since␈α∀this␈α∀is␈α∀computer␈α∀science␈α∀we␈α∀should␈α∀give␈α∀consideration␈α∪to
␈↓ ↓H␈↓efficiency.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 27␈↓␈αIf␈αwe␈αwish␈αLISP␈αto␈αrun␈αon␈αa␈αconventional␈αmachine␈αwe␈αhave␈αto␈αrepresent␈αLISP's␈αdata␈αstructures
␈↓ ↓H␈↓and␈α∂algorithms␈α∂in␈α∂a␈α∂manner␈α∂understandable␈α∂to␈α∂that␈α∂hardware.␈α∂This␈α∂task␈α∂is␈α∂the␈α∂subject␈α∂of␈α∂later
␈↓ ↓H␈↓chapters in the book.
␈↓ ↓H␈↓␈↓↓1.7␈↓ π*Lists: Representations of Sequences 31␈↓
␈↓ ↓H␈↓A reasonable choice for a representation of sequences as S-expressions is the following:
␈↓ ↓H␈↓␈↓ ¬7␈↓λr␈↓∞(␈↓<indiv>␈↓∞)␈↓ = <atom>
␈↓ ↓H␈↓␈↓ ∧rand for ␈↓λα␈↓β1␈↓, ..., ␈↓λα␈↓βn␈↓ in ␈↓<seq elem>␈↓:
␈↓"␈↓ ↓H␈↓∂␈↓ αX ␈↓λr␈↓∞(␈↓↓ (␈↓λα␈↓β1␈↓, ..., ␈↓λα␈↓βn␈↓↓) ␈↓∞)␈↓ = ␈↓∂␈↓ ¬h /\
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h / \
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h ␈↓λr␈↓∞(␈↓↓ ␈↓λα␈↓β1␈↓↓ ␈↓∞)␈↓∂ \
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h \
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h \
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h /\
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h / \
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h ␈↓λr␈↓∞(␈↓↓ ␈↓λα␈↓β2␈↓↓ ␈↓∞)␈↓∂
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h ...
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h \
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h /\
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h / \
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h / \
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h / ␈↓αNIL␈↓∂
␈↓"␈↓ ↓H␈↓∂␈↓ αX␈↓ ¬h ␈↓λr␈↓∞(␈↓↓ ␈↓λα␈↓βn␈↓↓ ␈↓∞)
␈↓ ↓H␈↓The␈αright-hand␈αbranch␈αin␈αthis␈αLISP-tree␈αrepresentation␈αof␈αa␈αsequence␈αwill␈αalways␈αpoint␈αto␈αthe␈αrest
␈↓ ↓H␈↓of␈α∩the␈α∩sequence␈α∩or␈α∩will␈α∩be␈α∩the␈α∩atom␈α∩␈↓αNIL␈↓.␈α∩ Notice␈α∩that␈α∩the␈α∩description␈α∩of␈α∩the␈α∩␈↓λr␈↓-mapping␈α∩is
␈↓ ↓H␈↓recursive. Thus for example:
␈↓"␈↓ ↓H␈↓∂␈↓ β( ␈↓λr␈↓∞(␈↓↓ ((A,B,C),(D)) ␈↓∞)␈↓ = ␈↓∂␈↓ ελ /\
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ / \
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ / \
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ ␈↓λr␈↓∞(␈↓↓ (A,B,C) ␈↓∞)␈↓∂ \
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ \
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ \
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ /\
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ / \
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ / ␈↓αNIL␈↓∂
␈↓"␈↓ ↓H␈↓∂␈↓ β(␈↓ ελ ␈↓λr␈↓∞(␈↓↓ (D) ␈↓∞)␈↓∂
␈↓ ↓H␈↓which␈α∞will␈α∞finally␈α∞expand␈α∞to␈α∞␈↓α((A␈α
.␈α∞(B␈α∞.␈α∞(C␈α∞.␈α∞NIL)))␈α∞.␈α
((D␈α∞.␈α∞NIL)␈α∞.␈α∞NIL))␈↓␈α∞since␈α∞␈↓λr␈↓∞(␈↓↓ (A,B,C) ␈↓∞)␈↓␈α
is
␈↓ ↓H␈↓␈↓α(A . (B . (C . NIL)))␈↓ and ␈↓λr␈↓∞(␈↓↓ (D) ␈↓∞)␈↓ is ␈↓α(D . NIL)␈↓.
␈↓ ↓H␈↓For␈α∪convenience␈α∩sake␈α∪we␈α∩will␈α∪carry␈α∪over␈α∩the␈α∪sequence␈α∩notation␈α∪-- ␈↓↓(A, B, C)␈↓ --␈α∩to␈α∪that␈α∪for␈α∩the
␈↓ ↓H␈↓representation␈α∨in␈α∨LISP␈α≡-- ␈↓α(A, B, C)␈↓ --␈↓π 28␈↓␈α∨thinking␈α∨of␈α≡␈↓α(A, B, C)␈↓␈α∨as␈α∨an␈α∨abbreviation␈α≡for
␈↓ ↓H␈↓␈↓α(A . (B . (C . NIL)))␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓α␈↓π 28␈↓α ␈↓Be aware that ␈↓αA␈↓ is an atom and ␈↓↓A␈↓ is a sequence element; they are not the same data structure.
␈↓ ↓H␈↓␈↓↓32 Symbolic expressions␈↓ 71.7␈↓
␈↓ ↓H␈↓Next,␈α⊂what␈α⊂about␈α⊂a␈α∂representation␈α⊂for␈α⊂the␈α⊂empty␈α⊂sequence?␈α∂Looking␈α⊂at␈α⊂the␈α⊂representation␈α⊂of␈α∂a
␈↓ ↓H␈↓non-empty␈α
sequence␈α
it␈α
appears␈α
natural␈α
to␈α
take␈α␈↓αNIL␈↓␈α
as␈α
␈↓λr␈↓∞(␈↓↓( )␈↓∞)␈↓␈α
since␈α
after␈α
you␈α
have␈α
removed␈αall␈α
the
␈↓ ↓H␈↓elements from the sequence ␈↓αNIL␈↓ is all that is left in the representation. To be consistent then:
␈↓ ↓H␈↓␈↓ ¬a␈↓λr␈↓∞(␈↓↓ ( ) ␈↓∞)␈↓ = ␈↓αNIL␈↓.
␈↓ ↓H␈↓This␈αgives␈αus␈αa␈αcomplete␈αspecification␈αof␈αthe␈α␈↓λr␈↓-mapping␈αfor␈αthe␈αdomain;␈αwe␈αhave␈αrepresented␈αthe
␈↓ ↓H␈↓abstract␈α⊂domain␈α⊂of␈α⊂sequences␈α⊃in␈α⊂a␈α⊂subset␈α⊂of␈α⊂the␈α⊃domain␈α⊂of␈α⊂Symbolic␈α⊂Expressions.␈α⊃The␈α⊂S-expr
␈↓ ↓H␈↓representation of a sequence is called a ␈↓↓list␈↓; and we will refer to the abbreviation,
␈↓ ↓H␈↓␈↓ β+␈↓α(␈↓λα␈↓β1␈↓α, ..., ␈↓λα␈↓βn␈↓α)␈↓ for ␈↓α(␈↓λα␈↓β1␈↓α . (␈↓λα␈↓β2␈↓α . ... (␈↓λα␈↓βn␈↓α . NIL) ...))␈↓ as ␈↓↓list-notation␈↓.
␈↓ ↓H␈↓Sequences␈αare␈αthe␈αabstract␈α
data␈αstructure;␈αlists␈αare␈αtheir␈α
representation.␈α Since␈αthe␈αatom␈α
␈↓αNIL␈↓␈αtakes
␈↓ ↓H␈↓on special significance in list-notation it is endowed with the special name ␈↓↓list terminator␈↓.
␈↓ ↓H␈↓And a notational point: in graphical interpretation of list-notation it is often convenient to write:
␈↓"␈↓ ↓H␈↓
␈↓ βx⊂αααπααααα⊃␈↓ πλ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
␈↓ βx~ ~ NIL ~ ␈↓as␈↓
␈↓ πλ ~ ~≤'~
␈↓"␈↓ ↓H␈↓
␈↓ βx%ααα∀ααααα$␈↓ πλ %ααα∀αα$
␈↓ ↓H␈↓For example ␈↓α(A, (B, C), D)␈↓ is:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ A ~ #αβα→~ # ~ #αβα→~ D ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %αβα∀ααα$ %ααα∀αα$
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
~ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%αα→~ B ~ #αβα→~ C ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓or,␈α∂in␈α⊂"dotted-pair"␈α∂notation:␈α∂␈↓α␈α⊂(A␈α∂.␈α∂((B␈α⊂.␈α∂(C␈α⊂.␈α∂NIL))␈α∂.␈α⊂(D␈α∂.␈α∂NIL)))␈↓.␈α⊂ Finally,␈α∂in␈α⊂list-notation␈α∂the
␈↓ ↓H␈↓commas can be replaced by spaces␈↓π 29␈↓
␈↓ ↓H␈↓␈↓ ∧|e.g. ␈↓α(A, (B, C), D) = (A (B C) D).
␈↓ ↓H␈↓α␈↓but beware: the "dots" in dot-notation are ␈↓↓never␈↓ optional!
␈↓ ↓H␈↓␈↓ ∧uthat is ␈↓α(A . (B . C)) ␈↓ ≠␈↓α (A (B C)).
␈↓ ↓H␈↓At␈α∩this␈α⊃point␈α∩we␈α∩have␈α⊃an␈α∩intuitive␈α⊃understanding␈α∩of␈α∩what␈α⊃we␈α∩mean␈α⊃by␈α∩"sequence";␈α∩we␈α⊃have
␈↓ ↓H␈↓described␈α∪selectors,␈α∪constructors,␈α∪and␈α∪recognizers,␈α∪albeit␈α∪at␈α∪an␈α∪abstract␈α∪level,␈α∪for␈α∩manipulating
␈↓ ↓H␈↓sequences,␈αand␈αwe␈αhave␈αrepresented␈αour␈αnotion␈αof␈αsequences␈αas␈αa␈αsubset␈αof␈αthe␈αS-expressions␈αcalled
␈↓ ↓H␈↓lists.␈α The␈αfinal␈αstep␈α
is␈αto␈αrepresent␈αour␈αsequence-manipulators␈α
as␈αcertain␈αLISP␈αfunctions.␈α Let␈α
␈↓αfirst␈↓βr␈↓
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 29␈↓␈αThis␈α
convention␈αis␈α
one␈αof␈αthe␈α
few␈αinstances␈α
of␈αa␈α"good"␈α
bug.␈αThe␈α
early␈αLISP␈α
papers␈αrequired
␈↓ ↓H␈↓full␈αuse␈αof␈αcommas,␈αbut␈αdue␈αto␈αa␈αprogramming␈αerror␈αin␈αthe␈αLISP␈αoutput␈αroutine,␈αlists␈αwere␈αprinted
␈↓ ↓H␈↓without commas. It looked so much better that the bug became institutionalized.
␈↓ ↓H␈↓␈↓↓1.7␈↓ π*Lists: Representations of Sequences 33␈↓
␈↓ ↓H␈↓be␈α∂a␈α∞LISP␈α∂function␈α∂which␈α∞will␈α∂represent␈α∂the␈α∞sequence␈α∂operation␈α∂␈↓αfirst␈↓␈↓π 30␈↓.␈α∞ Then␈α∂for␈α∂example␈α∞we
␈↓ ↓H␈↓might expect:
␈↓ ↓H␈↓α␈↓ ∧/first␈↓βr␈↓α[(A, B, C)] = ␈↓λr␈↓∞(␈↓α first[␈↓↓(A, B, C)␈↓α] ␈↓∞)␈↓α = A␈↓.
␈↓ ↓H␈↓The␈α∪problem␈α∪is␈α∪that␈α∪this␈α∪line␈α∪is␈α∪not␈α∪quite␈α∪right.␈α∪ LISP␈α∪functions␈α∪expect␈α∪their␈α∪inputs␈α∪to␈α∪be
␈↓ ↓H␈↓S-expressions but ␈↓α(A, B, C)␈↓ is ␈↓↓not␈↓ an S-expression. To be correct we ␈↓↓should␈↓ have written:
␈↓ ↓H␈↓␈↓ ¬␈↓αfirst␈↓βr␈↓α[(A .(B . (C . NIL)))] = A␈↓β
␈↓ ↓H␈↓It␈α
might␈α∞be␈α
argued␈α∞that␈α
␈↓α(A,␈α∞B,␈α
C)␈↓␈α∞is␈α
just␈α∞a␈α
convenient␈α∞abbreviation␈α
for␈α∞␈↓α(A . (B . (C . NIL)))␈↓,␈α
but
␈↓ ↓H␈↓even␈αso,␈α
if␈αwe␈α
wish␈αthe␈α
machine␈αto␈α
use␈αthe␈α
abbreviation␈αwe␈α
must␈αbe␈α
able␈αto␈α
express␈αthat␈α
translation
␈↓ ↓H␈↓scheme␈αto␈α
the␈αmachine.␈α We␈α
must␈αtherefore␈αexamine␈α
the␈αimplications␈αof␈α
the␈αnotation.␈αClearly␈α
it␈αis
␈↓ ↓H␈↓easier␈α∞to␈α∞read␈α∞and␈α∞write␈α∂in␈α∞list␈α∞notation␈α∞and,␈α∞as␈α∞long␈α∂as␈α∞we␈α∞perform␈α∞only␈α∞list-operations␈α∂on␈α∞lists,
␈↓ ↓H␈↓there␈αis␈αno␈αreason␈αto␈αlook␈αat␈αthe␈αunderlying␈αdotted-pair␈αrepresentation␈↓π 31␈↓.␈α However,␈αwe␈αmust␈αkeep
␈↓ ↓H␈↓in␈α∞mind␈α∞that␈α
list␈α∞operations␈α∞are␈α∞carried␈α
out␈α∞on␈α∞the␈α
machine␈α∞using␈α∞the␈α∞dotted-pair␈α
representation.
␈↓ ↓H␈↓␈↓↓We␈↓␈α∀might␈α∀carry␈α∀out␈α∀the␈α∪"list-to-dotted-pair"␈α∀transformations␈α∀implicitly,␈α∀but␈α∀a␈α∀machine␈α∪which
␈↓ ↓H␈↓evaluates␈α
LISP␈αexpressions␈α
will␈αhave␈α
to␈αhave␈α
an␈αexplict␈α
transformation␈αmechanism.␈α
So␈αa␈α
necessary
␈↓ ↓H␈↓part␈αof␈αour␈αrepresentation␈αof␈αsequences␈αis␈αthe␈αspecification␈αof␈αtransformations␈αbetween␈αthe␈αabstract
␈↓ ↓H␈↓data structure notation and the notation of the underlying representation.
␈↓ ↓H␈↓We␈α∀can␈α∪give␈α∀representations␈α∪for␈α∀the␈α∪sequence␈α∀operations.␈α∪ We␈α∀should␈α∪continue␈α∀to␈α∀write␈α∪the
␈↓ ↓H␈↓subscript␈α␈↓βr␈↓␈αon␈α
the␈αLISP␈αrepresentation␈αof␈α
a␈αsequence␈αoperation,␈αlike␈α
␈↓αseq␈↓␈αbeing␈αrepresented␈α
by␈α␈↓αseq␈↓βr␈↓.
␈↓ ↓H␈↓In␈α∞most␈α∞circumstances␈α∞the␈α∞distinction␈α∞between␈α∂abstraction␈α∞and␈α∞representation␈α∞will␈α∞be␈α∞clear,␈α∂so␈α∞we
␈↓ ↓H␈↓will␈α⊃usually␈α⊃omit␈α⊂the␈α⊃subscript.␈α⊃ The␈α⊃construction␈α⊂of␈α⊃a␈α⊃sequence␈α⊂from␈α⊃an␈α⊃arbitrary␈α⊃number␈α⊂of
␈↓ ↓H␈↓elements will be represented by a LISP function ␈↓αseq␈↓βr␈↓. We will use ␈↓αlist␈↓ interchangeably with ␈↓αseq␈↓βr␈↓.
␈↓ ↓H␈↓␈↓ ¬h␈↓λr␈↓∞(␈↓α seq ␈↓∞)␈↓α = list
␈↓ ↓H␈↓␈↓αlist[␈↓λα␈↓β1␈↓α;␈α⊂␈↓λα␈↓β2␈↓α;␈α⊂...␈α∂;␈↓λα␈↓βn␈↓α]␈↓␈α⊂generates␈α⊂a␈α⊂list␈α∂consisting␈α⊂of␈α⊂the␈α∂␈↓λα␈↓βi␈↓␈α⊂arguments.␈α⊂That␈α⊂is,␈α∂for␈α⊂n␈↓ ≥␈↓1,␈α⊂␈↓αlist␈↓␈α⊂is␈α∂the
␈↓ ↓H␈↓appropriately nested composition of ␈↓αcons␈↓es:
␈↓ ↓H␈↓␈↓ β3␈↓αcons[␈↓λα␈↓β1␈↓α;cons[␈↓λα␈↓β2␈↓α; ... cons[␈↓λα␈↓βn␈↓α;NIL]] ...] ␈↓, and for n = 0, ␈↓αlist[ ] = ( )␈↓.
␈↓ ↓H␈↓Examples:
␈↓ ↓H␈↓α␈↓ ¬blist[A;B] = (A B)
␈↓ ↓H␈↓α␈↓ ¬Flist[A;B;C] = (A B C)
␈↓ ↓H␈↓α␈↓ ∧:list[A;list[B;C]] = list[A;(B C)] = (A (B C))
␈↓ ↓H␈↓α␈↓ ¬Ylist[NIL] = (NIL)
␈↓ ↓H␈↓Notice␈α
that␈α∞␈↓αlist␈↓␈α
is␈α
␈↓↓not␈↓␈α∞strictly␈α
a␈α
LISP␈α∞function;␈α
it␈α
␈↓↓does␈↓␈α∞evaluate␈α
its␈α
arguments,␈α∞but␈α
it␈α
can␈α∞take␈α
an
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 30␈↓ Indeed, once the ␈↓λr␈↓-mapping is defined on the ␈↓↓domain␈↓ it is induced on the ␈↓↓operations␈↓.
␈↓ ↓H␈↓␈↓π 31␈↓␈α⊃Indeed,␈α∩a␈α⊃strong␈α∩case␈α⊃can␈α∩be␈α⊃made␈α⊃for␈α∩␈↓↓never␈↓␈α⊃allowing␈α∩any␈α⊃operations␈α∩on␈α⊃lists␈α∩␈↓↓except␈↓␈α⊃list
␈↓ ↓H␈↓operations! See the discussion of type-faults on page 22 and page 223.
␈↓ ↓H␈↓␈↓↓34 Symbolic expressions␈↓ 71.7␈↓
␈↓ ↓H␈↓arbitrary␈αnumber␈αof␈αthem.␈αOn␈αpage 18␈αwe␈αrequired␈αthat␈αLISP␈αfunctions␈αbe␈αof␈αfixed␈αarity.␈α For␈αthe
␈↓ ↓H␈↓moment,␈α
␈↓αlist␈↓␈α
is␈αsimply␈α
a␈α
notational␈αabbreviation␈α
for␈α
nested␈αapplications␈α
of␈α
␈↓αcons␈↓.␈α The␈α
representation
␈↓ ↓H␈↓of␈α
the␈α
selector␈αfunctions␈α
should␈α
be␈α
apparent␈αfrom␈α
the␈α
graphical␈α
representation.␈αWe␈α
leave␈α
it␈α
as␈αan
␈↓ ↓H␈↓exercise␈αfor␈α
the␈αreader␈α
to␈αspecify␈α
representations␈αfor␈αthese␈α
functions;␈αhowever,␈α
here␈αare␈α
a␈αfew␈αof␈α
the
␈↓ ↓H␈↓other representations:
␈↓ ↓H␈↓␈↓ ¬F␈↓λr␈↓∞(␈↓α isindiv ␈↓∞)␈↓α = atom
␈↓ ↓H␈↓α␈↓ ∧␈␈↓λr␈↓∞(␈↓α isseq ␈↓∞)␈↓α = isstrictlist␈↓ where:
␈↓ ↓H␈↓α␈↓ αxisstrictlist[x] <=␈↓ ∧H[atom[x] → [eq[x; NIL] → ␈↓
t␈↓α; ␈↓
t␈↓α → ␈↓
f␈↓α];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧H islistelement[car[x]] → isstrictlist[cdr[x]];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧H ␈↓
t␈↓α → ␈↓
f␈↓α]
␈↓ ↓H␈↓α␈↓ αxislistelement[x] <= [atom[x] → ␈↓
t␈↓α; ␈↓
t␈↓α → isstrictlist[x]]
␈↓ ↓H␈↓The predicate ␈↓αatom␈↓ does not quite characterize ␈↓αisindiv␈↓. We have been assuming that:
␈↓ ↓H␈↓␈↓ βs␈↓λr␈↓∞(␈↓αf[t␈↓β1␈↓α; ...; t␈↓βn␈↓α]␈↓∞)␈↓ = ␈↓λr␈↓∞(␈↓αf␈↓∞)␈↓α[␈↓λr␈↓∞(␈↓αt␈↓β1␈↓α␈↓∞)␈↓α;␈↓λr␈↓∞(␈↓αt␈↓β2␈↓α␈↓∞)␈↓α; ...; ␈↓λr␈↓∞(␈↓αt␈↓βn␈↓α␈↓∞)␈↓α]
␈↓ ↓H␈↓α␈↓but ␈↓ ∧C␈↓λr␈↓∞(␈↓αisindiv[( )]␈↓∞)␈↓ ␈↓ ≠␈↓ ␈↓λr␈↓∞(␈↓αisindiv␈↓∞)␈↓α[␈↓λr␈↓∞(␈↓α( )␈↓∞)␈↓α]␈↓
␈↓ ↓H␈↓Some␈α∂descriptions␈α∞of␈α∂LISP␈α∞use␈α∂this␈α∂strict␈α∞definition␈α∂of␈α∞lists,␈α∂so␈α∂that␈α∞elements␈α∂of␈α∞a␈α∂list␈α∂are␈α∞either
␈↓ ↓H␈↓atomic␈α∞or␈α
are␈α∞lists␈α
themselves.␈α∞ In␈α
practice␈α∞it␈α∞is␈α
often␈α∞convenient␈α
to␈α∞allow␈α
elements␈α∞of␈α
a␈α∞list␈α∞to␈α
be
␈↓ ↓H␈↓arbitrary␈α∩S-expressions.␈α∩This␈α⊃more␈α∩liberal␈α∩interpretation␈α⊃of␈α∩lists␈α∩is␈α⊃expressed␈α∩by␈α∩the␈α⊃following
␈↓ ↓H␈↓recognizer:
␈↓ ↓H␈↓␈↓ βa␈↓αislist[x] <= [atom[x] →[eq[x;NIL]→␈↓
t␈↓α;␈↓
t␈↓α→␈↓
f␈↓α]; ␈↓
t␈↓α→islist[cdr[x]] ]
␈↓ ↓H␈↓Therefore␈α
␈↓α(A, (A . B), C)␈↓␈α
is␈αa␈α
list␈α
of␈α
three␈αelements.␈α
But␈α
beware:␈α␈↓↓(A, (A . B), C)␈↓␈α
is␈α
␈↓↓not␈↓␈α
a␈αsequence,
␈↓ ↓H␈↓and neither is ␈↓α(A, (A . B), C)␈↓.
␈↓ ↓H␈↓Since lists may have dotted pairs as elements, it is natural to extend ␈↓αlist␈↓ to handle such cases:
␈↓ ↓H␈↓α␈↓ ∧Olist[cons[A;B];car[(A . B)]] = ((A . B) A)
␈↓ ↓H␈↓␈↓↓1.7␈↓ π*Lists: Representations of Sequences 35␈↓
␈↓ ↓H␈↓To␈αsummarize␈α
the␈αaccomplishments␈α
of␈αthis␈α
section,␈αwe␈αhave␈α
in␈αeffect␈α
added␈αa␈α
␈↓↓new␈↓␈αdata␈αstructure␈α
to
␈↓ ↓H␈↓the repertoire of LISP. The addition process included:
␈αAH␈↓␈↓↓1.␈α⊂ The␈α⊃abstract␈α⊂operations.␈↓␈α⊃We␈α⊂give␈α⊃constructors,␈α⊂selectors,␈α⊃and␈α⊂predicates␈α⊃for␈α⊂the
␈↓ ↓H␈↓␈↓ αhrecognition of instances of the data structure.
␈↓ ↓H␈↓␈↓↓2.␈α The␈αunderlying␈αrepresentation.␈↓␈αWe␈αmust␈αshow␈αhow␈αthe␈αnew␈αdata␈αstructure␈αcan␈αbe
␈↓ ↓H␈↓␈↓ αhrepresented in terms of existing data structures.
␈↓ ↓H␈↓␈↓↓3.␈α Abstract␈α
operations␈αas␈αconcrete␈α
operations.␈↓␈αWe␈αmust␈α
write␈αLISP␈α
functions␈αwhich
␈↓ ↓H␈↓␈↓ αhfaithfully␈α⊂mirror␈α⊂the␈α⊂intended␈α∂meaning␈α⊂of␈α⊂the␈α⊂abstract␈α⊂operations␈α∂when
␈↓ ↓H␈↓␈↓ αhinterpreted in the underlying representation.
␈↓ ↓H␈↓␈↓↓4.␈α The␈α
input/output␈αtransformations.␈↓␈α
We␈αshould␈α
give␈αconventions␈α
for␈αtransforming
␈↓ ↓H␈↓␈↓ αhto and from the internal representation.
␈↓ ↓H␈↓There␈α∩is␈α∩another␈α∩view␈α∪of␈α∩the␈α∩representability␈α∩of␈α∪data␈α∩structures␈α∩([Mor 74]).␈α∩We␈α∪use␈α∩␈↓↓transfer
␈↓ ↓H␈↓↓functions␈↓␈αwhich␈αare␈αmappings␈αbetween␈αthe␈αabstract␈αstructure␈αand␈αits␈αrepresentation.␈α We␈αneed␈αtwo
␈↓ ↓H␈↓transfer␈α
functions;␈α
a␈α
write-function,␈α
␈↓ W␈↓,␈α
to␈α
map␈α
the␈α
representations␈α
into␈α
the␈α
abstract␈α
objects;␈α
and␈αa
␈↓ ↓H␈↓read-function, ␈↓ R␈↓, to map the abstract objects to their representations.
␈↓ ↓H␈↓Consider␈α
the␈α
problem␈αof␈α
representing␈α
sequences.␈α
We␈αwant␈α
␈↓ R␈↓␈α
to␈α
map␈αfrom␈α
elements␈α
of␈α␈↓<seq␈α
elem>␈↓
␈↓ ↓H␈↓to␈α∞␈↓<sexpr>␈↓␈α∂(see␈α∞page 26␈α∞and␈α∂page 5);␈α∞and␈α∂we␈α∞want␈α∞␈↓ W␈↓␈α∂to␈α∞map␈α∞from␈α∂␈↓<sexpr>␈↓␈α∞to␈α∂␈↓<seq␈α∞elem>␈↓.
␈↓ ↓H␈↓Before we give such ␈↓ R␈↓ and ␈↓ W␈↓, let's see what they will do for us. We could define ␈↓αfirst␈↓βr␈↓ such that:
␈↓ ↓H␈↓␈↓ ¬<␈↓αfirst␈↓βr␈↓α[x] = ␈↓ W␈↓α[car[␈↓ R␈↓α[x]]]
␈↓ ↓H␈↓What␈α
the␈α
equation␈α
says␈α
is␈α
that␈α
given␈α
a␈α
sequence␈α
␈↓αx␈↓,␈α
we␈α
can␈α
map␈α
it␈α
to␈α
the␈α
S-expression␈α
representation
␈↓ ↓H␈↓using␈α␈↓ R␈↓;␈α
the␈αresult␈α
of␈αthis␈α
map␈αis␈α
an␈αS-expr␈αand␈α
therefore␈αsuitable␈α
fare␈αfor␈α
␈↓αcar␈↓;␈αthe␈α
result␈αof␈αthe␈α
␈↓αcar␈↓
␈↓ ↓H␈↓operation␈α
is␈αthen␈α
mapped␈α
back␈αinto␈α
the␈α
set␈αof␈α
sequence␈αelements␈α
by␈α
␈↓ W␈↓.␈α The␈α
other␈α
operations␈αfor
␈↓ ↓H␈↓manipulating␈α∞sequences␈α∞can␈α∞be␈α∞described␈α∞similarly.␈α∞ With␈α∞this␈α∞introduction,␈α∞here␈α∞are␈α∞appropriate
␈↓ ↓H␈↓transfer functions:
␈↓ ↓H␈↓α␈↓ W␈↓α[e] <=␈↓ α8[isnil[e] → mknull[];
␈↓ ↓H␈↓α␈↓ α8 atom[e] → mkindiv[e];
␈↓ ↓H␈↓α␈↓ α8 ␈↓
t␈↓α → concat[␈↓ W␈↓α[car[e]];␈↓ W␈↓α[cdr[e]]] ]
␈↓ ↓H␈↓α␈↓ R␈↓α[l] <=␈↓ α([null[l] → NIL;
␈↓ ↓H␈↓α␈↓ α( isindiv[l] → atomize[l];
␈↓ ↓H␈↓α␈↓ α( ␈↓
t␈↓α → cons[␈↓ R␈↓α[first[l]];␈↓ R␈↓α[rest[l]]] ]
␈↓ ↓H␈↓We␈α
have␈α
seen␈α
all␈α
of␈α∞the␈α
functions␈α
and␈α
predicates␈α
involved␈α
in␈α∞␈↓ R␈↓␈α
and␈α
␈↓ W␈↓␈α
except␈α
the␈α∞three␈α
␈↓αatomize␈↓,
␈↓ ↓H␈↓␈↓αmknull␈↓␈αand␈α␈↓αmkindiv␈↓.␈αIn␈αterms␈αof␈αour␈αcurrent␈αrepresentation␈αof␈αsequences,␈αthese␈αthree␈αfunctions␈αare
␈↓ ↓H␈↓essentially␈α⊂the␈α⊃identity␈α⊂function,␈α⊂␈↓αi[x] <= x␈↓.␈α⊃However␈α⊂that␈α⊃is␈α⊂true␈α⊂␈↓↓only␈↓␈α⊃because␈α⊂of␈α⊃the␈α⊂particular
␈↓ ↓H␈↓␈↓↓36 Symbolic expressions␈↓ 71.7␈↓
␈↓ ↓H␈↓representations␈α∂that␈α∂we␈α∂picked;␈α∂the␈α∂functions␈α∂need␈α∂not␈α∂be␈α∂so␈α∂simple.␈α∂ A␈α∂more␈α∂careful␈α∂inspection
␈↓ ↓H␈↓would␈α∀show␈α∀that␈α∀␈↓αmkindiv␈↓␈α∃expects␈α∀as␈α∀input␈α∀an␈α∃atomic␈α∀S-expression␈α∀and␈α∀outputs␈α∃a␈α∀sequence
␈↓ ↓H␈↓individual;␈α␈↓αatomize␈↓␈αacts␈αconversely.␈α
If␈αthe␈αrepresentations␈αof␈α
the␈αatomic␈αS-expressions␈αwere␈α
different
␈↓ ↓H␈↓from the representations of sequence individuals, then we would have some work to do.
␈↓ ↓H␈↓We␈α⊂review␈α⊂what␈α∂has␈α⊂transpired␈α⊂since␈α⊂it␈α∂is␈α⊂a␈α⊂model␈α∂of␈α⊂what␈α⊂is␈α⊂to␈α∂come.␈α⊂ We␈α⊂developed␈α⊂a␈α∂new
␈↓ ↓H␈↓abstract␈α⊃data␈α⊂structure␈α⊃called␈α⊃sequences;␈α⊂discussed␈α⊃notational␈α⊂conventions␈α⊃for␈α⊃writing␈α⊂sequences;
␈↓ ↓H␈↓described␈α∂operations␈α∂and␈α⊂pertinent␈α∂control␈α∂structures␈α∂for␈α⊂writing␈α∂algorithms;␈α∂and␈α⊂finally␈α∂showed
␈↓ ↓H␈↓that␈α∞it␈α
was␈α∞possible␈α∞to␈α
represent␈α∞sequences␈α
in␈α∞the␈α∞previously␈α
developed␈α∞domain␈α
of␈α∞S-exprs.␈α∞If␈α
we
␈↓ ↓H␈↓had␈α
a␈α
machine␈α
which␈α
could␈α
execute␈α
S-expr␈α
algorithms␈α
we␈α
could␈α
encapsulate␈α
that␈α
machine␈α
within
␈↓ ↓H␈↓the␈α
␈↓λr␈↓-mapping␈αsuch␈α
that␈αwe␈α
could␈α
write␈αin␈α
sequence-notation␈αand␈α
have␈αit␈α
translated␈α
internally␈αto
␈↓ ↓H␈↓S-expr␈α
form;␈α
we␈α
could␈α
write␈α
sequence-algorithms␈α
and␈α
have␈α
them␈α
execute␈α
correctly␈α
using␈αthe␈α
␈↓λr␈↓-maps
␈↓ ↓H␈↓of␈α
the␈α
sequence␈α
primitives;␈α
and␈α
finally␈αit␈α
would␈α
produce␈α
sequence-output␈α
rather␈α
than␈α
the␈αinternal
␈↓ ↓H␈↓S-expr␈α∂form.␈α∞For␈α∂all␈α∞intents␈α∂and␈α∞purposes␈α∂our␈α∞augmented␈α∂LISP␈α∞machine␈α∂understands␈α∞sequences.
␈↓ ↓H␈↓Indeed,␈α
this␈α
is␈α∞the␈α
way␈α
most␈α
LISP␈α∞implementations␈α
are␈α
organized;␈α
input␈α∞may␈α
either␈α
be␈α∞in␈α
S-expr
␈↓ ↓H␈↓form␈α
or␈α
list-notation;␈α
internally␈αall␈α
data␈α
structures␈α
are␈α
stored␈αas␈α
S-exprs;␈α
all␈α
algorithms␈α
operate␈αon
␈↓ ↓H␈↓the␈α∀S-expr␈α∃form;␈α∀and␈α∃finally,␈α∀any␈α∃S-exprs␈α∀which␈α∃can␈α∀be␈α∃interpreted␈α∀as␈α∃lists␈α∀are␈α∃output␈α∀in
␈↓ ↓H␈↓list-notation.
␈↓ ↓H␈↓We␈αwill␈αapproach␈αthe␈αother␈αabstract␈αdata␈αstructure␈αproblems␈αin␈αa␈αsimilar␈αmanner,␈αfirst␈αdeveloping
␈↓ ↓H␈↓the␈α∂data␈α∞structures␈α∂independent␈α∞of␈α∂their␈α∞representation,␈α∂and␈α∞later␈α∂showing␈α∞how␈α∂to␈α∂represent␈α∞this
␈↓ ↓H␈↓new␈α⊃domain␈α∩in␈α⊃terms␈α⊃of␈α∩some␈α⊃previously␈α⊃understood␈α∩domain.␈α⊃We␈α⊃will␈α∩see␈α⊃in␈α∩Section 9.4␈α⊃that
␈↓ ↓H␈↓much␈αof␈αthe␈αmapping␈αfrom␈αinput␈αthrough␈αoutput␈αcan␈αbe␈αspecified␈αin␈αa␈αnatural␈αstyle␈αand␈αLISP␈αcan
␈↓ ↓H␈↓automatically generate the necessary input and output programs.
␈↓ ↓H␈↓␈↓ ∧v␈↓↓Problems involving list-notation␈↓
␈↓ ↓H␈↓I␈α∞Discuss␈α∞␈↓αcons[␈↓λα␈↓β1␈↓α;cons[␈↓λα␈↓β2␈↓α;␈↓λα␈↓β3␈↓α]]␈↓␈α∂as␈α∞opposed␈α∞to␈α∞␈↓αcons[␈↓λα␈↓β1␈↓α;cons[␈↓λα␈↓β2␈↓α;␈α∂cons[␈↓λα␈↓β3␈↓α;␈α∞NIL]]]␈↓␈α∞as␈α∂a␈α∞representation
␈↓ ↓H␈↓for ␈↓α(␈↓λα␈↓β1␈↓α, ␈↓λα␈↓β2␈↓α, ␈↓λα␈↓β3␈↓α)␈↓.
␈↓ ↓H␈↓II Translate the following lists into S-expr dotted-pair notation.
␈↓ ↓H␈↓␈↓ βo␈↓↓1.␈↓α (A B C) ␈↓↓2.␈↓α (A) ␈↓↓3.␈↓α ((A)) ␈↓↓4.␈↓α (A (B (C))) ␈↓↓5.␈↓α (NIL).
␈↓ ↓H␈↓Now go the other way and translate the following S-exprs into list notation.
␈↓ ↓H␈↓␈↓ βa␈↓↓6.␈↓α ((A . (B . NIL)) . ((C . NIL) . NIL)) ␈↓↓7.␈↓α (NIL . NIL)
␈↓ ↓H␈↓α␈↓ ∧=␈↓↓8.␈↓α (CONS . ((QUOTE . (A . NIL)) . NIL))
␈↓ ↓H␈↓III Evaluate the following:
␈↓ ↓H␈↓␈↓ ¬∀␈↓↓1.␈↓α first[(A B)] ␈↓↓2.␈↓α rest[(A B)]
␈↓ ↓H␈↓α␈↓ ∧b␈↓↓3.␈↓α concat[A;(B C)] ␈↓↓4.␈↓α concat[A;NIL]
␈↓ ↓H␈↓α␈↓ ∧+␈↓↓5.␈↓α concat[eq[A;A];(A B C)] ␈↓↓6.␈↓α first[rest[(A B)]]
␈↓ ↓H␈↓␈↓↓1.8␈↓
∧A Respite 37␈↓
␈↓ ↓H␈↓␈↓ ¬s␈↓↓1.8 A Respite␈↓
␈↓ ↓H␈↓␈↓ ∧λ"...I␈α
think␈αthat␈α
one␈αof␈α
the␈αchief␈α
difficulties␈αis␈α
that␈αthe␈α
general␈α
standard␈αof
␈↓ ↓H␈↓␈↓ ∧λprogramming␈αis␈αextremely␈α
low.␈α ...I␈αthink␈α
that␈αI␈αwould␈α
like␈αto␈αsuggest␈α
again
␈↓ ↓H␈↓␈↓ ∧λthat␈α
the␈α
general␈α
standards␈α
of␈αprogramming␈α
and␈α
the␈α
way␈α
in␈α
which␈αpeople
␈↓ ↓H␈↓␈↓ ∧λare␈α∩taught␈α∩to␈α∪program␈α∩is␈α∩abominable.␈α∩They␈α∪are␈α∩over␈α∩and␈α∪over␈α∩again
␈↓ ↓H␈↓␈↓ ∧λtaught␈α
to␈α
make␈αpuns;␈α
to␈α
do␈αshifts␈α
instead␈α
of␈αmultiplying␈α
when␈α
they␈αmean
␈↓ ↓H␈↓␈↓ ∧λmultiplying;␈αto␈αmultiply␈αwhen␈αthey␈α
mean␈αshifts;␈αto␈αconfuse␈αbit␈αpatterns␈α
and
␈↓ ↓H␈↓␈↓ ∧λnumbers␈α↔and␈α_generally␈α↔to␈α_say␈α↔one␈α↔thing␈α_when␈α↔they␈α_actually␈α↔mean
␈↓ ↓H␈↓␈↓ ∧λsomething␈α∩quite␈α∩different.␈α∩Now␈α∩this␈α∩is␈α∩the␈α∩standard␈α∩way␈α∩of␈α∪writing␈α∩a
␈↓ ↓H␈↓␈↓ ∧λprogram␈α∂and␈α∞they␈α∂take␈α∂great␈α∞pleasure␈α∂in␈α∂doing␈α∞so-"Isn't␈α∂it␈α∂wonderful?␈α∞It
␈↓ ↓H␈↓␈↓ ∧λsaves␈α∞a␈α∞quarter␈α∞of␈α∞a␈α
microsecond␈α∞somewhere␈α∞every␈α∞month".␈α∞Now␈α∞I␈α
think
␈↓ ↓H␈↓␈↓ ∧λwe␈α∞will␈α∞not␈α∞get␈α∞a␈α∞proper␈α∂standard␈α∞of␈α∞programming␈α∞...␈α∞until␈α∞we␈α∂can␈α∞have
␈↓ ↓H␈↓␈↓ ∧λsome␈αproper␈αprofessional␈αstandards␈αabout␈αhow␈αto␈αwrite␈αprograms;␈αand␈αthis
␈↓ ↓H␈↓␈↓ ∧λhas␈α∂to␈α∂be␈α∂done␈α∂by␈α∂teaching␈α∂people␈α∂right␈α∂at␈α∂the␈α∂beginning␈α∂how␈α⊂to␈α∂write
␈↓ ↓H␈↓␈↓ ∧λprogams properly ..."
␈↓ ↓H␈↓␈↓ ε⊗C. Strachey, ␈↓αConference on Software Engineering, 1968␈↓
␈↓ ↓H␈↓This␈α⊃section␈α∩summarizes␈α⊃and␈α∩reflects␈α⊃on␈α∩the␈α⊃material␈α∩of␈α⊃this␈α∩chapter.␈α⊃First␈α∩a␈α⊃reiteration␈α∩of␈α⊃a
␈↓ ↓H␈↓previous␈α∩admonition:␈α∪though␈α∩most␈α∪of␈α∩this␈α∩material␈α∪may␈α∩seem␈α∪quite␈α∩straightforward,␈α∪the␈α∩next
␈↓ ↓H␈↓chapter␈α
will␈α
begin␈α
to␈α
show␈α
you␈α
that␈α
things␈α∞are␈α
not␈α
all␈α
that␈α
trivial.␈α
LISP␈α
is␈α
quite␈α∞powerful.␈α
The
␈↓ ↓H␈↓preceding material ␈↓↓is␈↓ basic and the sooner it becomes second nature to you the better.
␈↓ ↓H␈↓A␈α∂second␈α∂admonition:␈α∂besides␈α∂learning␈α∂about␈α⊂the␈α∂basic␈α∂constructs␈α∂of␈α∂the␈α∂language,␈α⊂the␈α∂previous
␈↓ ↓H␈↓material␈α∂should␈α∂begin␈α∂to␈α∞convince␈α∂you␈α∂of␈α∂the␈α∞necessity␈α∂for␈α∂precise␈α∂specification␈α∂of␈α∞programming
␈↓ ↓H␈↓languages.␈αIn␈αparticular␈αwe␈αhave␈αseen␈αthat␈αthe␈αprocess␈αof␈αevaluation␈αof␈αexpressions␈αmust␈αbe␈αspelled
␈↓ ↓H␈↓out␈αquite␈αcarefully.␈αDifferent␈αevaluation␈αschemes␈αlead␈αto␈αquite␈αdifferent␈αeffects.␈αSince␈αevaluation␈α␈↓↓is␈↓
␈↓ ↓H␈↓the business of programming languages we'd better do all we can to make a precise specification.
␈↓ ↓H␈↓And␈α
a␈α
final␈α
warning:␈α
a␈α
major␈αpoint␈α
of␈α
this␈α
whole␈α
book␈α
is␈αto␈α
instill␈α
a␈α
respect␈α
for␈α
abstraction␈α
as␈αa
␈↓ ↓H␈↓tool␈α∀for␈α∀controlling␈α∀complexity␈α∀in␈α∃programming,␈α∀and␈α∀as␈α∀a␈α∀means␈α∀of␈α∃writing␈α∀implementation
␈↓ ↓H␈↓independent␈α
programs.␈αAs␈α
we␈α
begin␈αwriting␈α
more␈αcomplex␈α
algorithms,␈α
the␈αpower␈α
of␈αabstraction␈α
will
␈↓ ↓H␈↓become␈α
more␈α
apparent,␈α
but␈α
the␈α
lessons␈α∞we␈α
learned␈α
in␈α
representing␈α
sequences␈α
contain␈α∞the␈α
essential
␈↓ ↓H␈↓ideas of abstraction and representation.
␈↓ ↓H␈↓We␈α
have␈αnow␈α
seen␈αtwo␈α
examples␈αof␈α
abstract␈α
data␈αstructures.␈α
First,␈αwe␈α
studied␈αS-expressions␈α
without
␈↓ ↓H␈↓any␈αconsideration␈αfor␈αtheir␈αimplementation;␈αthey␈αwere␈αabstract␈αobjects␈αof␈αsufficient␈αinterest␈αin␈αtheir
␈↓ ↓H␈↓own␈α
right.␈α
We␈α
then␈α
introduced␈α
the␈α
operations␈α
on␈α
the␈α
data␈α
structures:␈α
␈↓αcar,␈α
cdr,␈α
cons,␈α
eq␈↓␈α∞and␈α
␈↓αatom␈↓.
␈↓ ↓H␈↓Finally␈αthe␈α␈↓↓control␈αstructures␈↓,␈αconditional␈αexpression␈αand␈αrecursion,␈αwere␈αgiven.␈αControl␈αstructures
␈↓ ↓H␈↓are␈α∪used␈α∀to␈α∪direct␈α∪the␈α∀flow␈α∪of␈α∪the␈α∀algorithm␈α∪as␈α∪it␈α∀executes.␈α∪ These␈α∪three␈α∀components,␈α∪data,
␈↓ ↓H␈↓operations,␈α
and␈α
control,␈α∞are␈α
the␈α
main␈α
ingredients␈α∞of␈α
any␈α
programming␈α
language.␈α∞ Most␈α
languages
␈↓ ↓H␈↓have␈αan␈αapparently␈αricher␈α
class␈αof␈αcontrol␈αdevices;␈α
"while"-statements␈αand␈α"DO"-loops␈αare␈α
examples.
␈↓ ↓H␈↓Later␈α
we␈αwill␈α
show␈αhow␈α
to␈αintroduce␈α
such␈αconstructs␈α
into␈αLISP.␈α
Most␈αcontrol␈α
structures␈αare␈α
explicit
␈↓ ↓H␈↓␈↓↓38 Symbolic expressions␈↓ 61.8␈↓
␈↓ ↓H␈↓language␈α
constructs␈α∞like␈α
the␈α∞conditional␈α
expression,␈α∞whereas␈α
recursion␈α∞is␈α
typically␈α∞implicit␈↓π 32␈↓.␈α
The
␈↓ ↓H␈↓interaction␈αbetween␈αrecursion␈α
and␈αthe␈αprocedure-calling␈αmechanism␈α
gives␈αLISP␈αa␈α
powerful␈αcontrol
␈↓ ↓H␈↓structure.
␈↓ ↓H␈↓As␈α⊂we␈α∂introduce␈α⊂each␈α⊂new␈α∂abstract␈α⊂data␈α∂structure␈α⊂we␈α⊂add␈α∂new␈α⊂operations␈α∂tailored␈α⊂to␈α⊂its␈α∂needs.
␈↓ ↓H␈↓When␈αwe␈αintroduced␈αsequences␈αwe␈αalso␈αintroduced␈α␈↓αfirst,␈αrest,␈αnull, ...␈↓,etc.␈α We␈αdid␈αnot␈αadd␈αany␈αnew
␈↓ ↓H␈↓control␈α
structure,␈α
though␈αa␈α
simpler␈α
control␈α
structure␈αwhich␈α
operated␈α
on␈α
sequences,␈αselecting␈α
elements
␈↓ ↓H␈↓and␈α∂performing␈α∂operations␈α⊂on␈α∂those␈α∂elements,␈α⊂might␈α∂be␈α∂useful.␈α⊂ There␈α∂is␈α∂a␈α⊂natural␈α∂relationship
␈↓ ↓H␈↓between␈αdata␈αstructure␈αand␈α
control␈αstructure;␈αsometimes␈αwe␈αcan␈α
exploit␈αit␈αto␈αgood␈α
measure.␈α When
␈↓ ↓H␈↓we␈α
consider␈α
abstract␈αdata␈α
structures␈α
in␈α
future␈αchapters␈α
we␈α
will␈α
again␈αsee␈α
the␈α
three␈αcomponents:␈α
data,
␈↓ ↓H␈↓operations, and control.
␈↓ ↓H␈↓The␈α
new␈α
feature␈α
which␈α
we␈α
considered␈αin␈α
discussing␈α
sequences␈α
was␈α
the␈α
problem␈α
of␈αrepresentation.
␈↓ ↓H␈↓We␈α
showed␈α
how␈αto␈α
represent␈α
sequences␈αin␈α
terms␈α
of␈α
S-expressions.␈αWe␈α
will␈α
continue␈αthis␈α
pyramiding
␈↓ ↓H␈↓of␈α
data␈α
structures␈α
in␈α
the␈α
future;␈α
we␈α
will␈α
consider␈α
our␈α
work␈α
done␈α
as␈α
soon␈α
as␈α
we␈α
have␈α
a␈α
representation
␈↓ ↓H␈↓of␈α
our␈α
new␈α
data␈α
structure␈α
in␈α
terms␈α
of␈αan␈α
existing␈α
one.␈α
Finally␈α
we␈α
will␈α
exhibit␈α
a␈α
representation␈αof
␈↓ ↓H␈↓the␈α∪underlying␈α∪layer␈α∪of␈α∪S-expressions.␈α∪Later␈α∪we␈α∪will␈α∪discuss␈α∪different␈α∪representations␈α∪of␈α∩data
␈↓ ↓H␈↓structures,␈α∪independent␈α∪of␈α∩their␈α∪possible␈α∪S-expression␈α∩representation;␈α∪there␈α∪are␈α∪data␈α∩structures
␈↓ ↓H␈↓which␈α
are␈α∞not␈α
best␈α∞represented␈α
as␈α∞S-expressions.␈α
A␈α∞further␈α
consideration␈α∞appears␈α
because␈α∞of␈α
the
␈↓ ↓H␈↓representation␈α∂issue;␈α∂even␈α∂though␈α∂we␈α∂have␈α∂represented␈α∂a␈α∂particular␈α∂data␈α∂structure␈α∂as␈α∂a␈α∂complex
␈↓ ↓H␈↓S-expression␈αwe␈αshould␈αnot␈αoperate␈αon␈αthat␈αrepresentation␈αwith␈αS-expression␈αfunctions.␈αWe␈αshould
␈↓ ↓H␈↓refrain␈α⊂from␈α⊂using␈α⊂␈↓αcar␈↓␈α⊃and␈α⊂␈↓αcdr␈↓␈α⊂on␈α⊂lists␈α⊂even␈α⊃though␈α⊂the␈α⊂representation␈α⊂is␈α⊂well-known.␈α⊃ In␈α⊂our
␈↓ ↓H␈↓representation␈α
of␈αlists␈α
we␈αcould␈α
find␈αthe␈α
n␈↓πth␈↓␈α
element␈αin␈α
a␈αlist␈α
by␈αusing␈α
␈↓αcad␈↓πn-1␈↓αr␈↓.␈αAnd␈α
we␈α
know␈αthat
␈↓ ↓H␈↓␈↓αcdr␈↓␈α
represents␈α
the␈α
␈↓αrest␈↓␈α
of␈α
the␈α
list.␈α
Though␈αour␈α
representation␈α
of␈α
sequences␈α
is␈α
such␈α
that␈α
␈↓αfirst␈↓,␈α␈↓αrest␈↓
␈↓ ↓H␈↓and␈α␈↓αconcat␈↓␈α
are␈αidentical␈α
to␈α␈↓αcar␈↓,␈α␈↓αcdr␈↓,␈α
and␈α␈↓αcons␈↓␈α
respectively,␈αwe␈αshould␈α
use␈αthe␈α
names␈α␈↓αfirst␈↓,␈α
␈↓αrest␈↓,␈αand
␈↓ ↓H␈↓␈↓αconcat␈↓␈α⊃to␈α⊃make␈α⊃it␈α⊃clear␈α⊃that␈α⊃we␈α⊃are␈α⊃operating␈α⊃on␈α⊃lists.␈α⊃ These␈α⊃representation-dependent␈α⊂coding
␈↓ ↓H␈↓tricks␈↓π 33␈↓ are dangerous. They are really type faults as discussed on page 22 and page 223.
␈↓ ↓H␈↓For␈α∞a␈α∞more␈α∂practical␈α∞benefit,␈α∞consider␈α∂the␈α∞problem␈α∞of␈α∞program␈α∂modification.␈α∞ We␈α∞might␈α∂wish␈α∞to
␈↓ ↓H␈↓change␈α⊂the␈α⊃representation␈α⊂of␈α⊂a␈α⊃data␈α⊂structure.␈α⊂If␈α⊃the␈α⊂programming␈α⊂has␈α⊃been␈α⊂done␈α⊂in␈α⊃terms␈α⊂of
␈↓ ↓H␈↓abstract␈α⊗operations␈α↔on␈α⊗abstract␈α↔data␈α⊗structures␈α⊗then␈α↔only␈α⊗those␈α↔functions␈α⊗which␈α↔relate␈α⊗the
␈↓ ↓H␈↓abstraction␈α
to␈α∞the␈α
representation␈α∞need␈α
be␈α∞changed.␈α
If␈α∞we␈α
had␈α∞used␈α
the␈α∞representation␈α
throughout
␈↓ ↓H␈↓the␈αprogram,␈αthen␈αevery␈αuse␈αof␈αthe␈αrepresentation␈αmust␈αbe␈αchanged.␈α While␈αwe␈αare␈αdiscussing␈αsome
␈↓ ↓H␈↓of␈αthe␈αmore␈αpractical␈α
implications␈αof␈αour␈αwork␈α
we␈αshould␈αdiscuss␈αhow␈α
␈↓λB␈↓␈αshould␈αbe␈αunderstood.␈α
As
␈↓ ↓H␈↓things␈αcurrently␈αstand,␈αthe␈αappearance␈αof␈α
␈↓λB␈↓␈αin␈αany␈αapplication␈αof␈αstrict␈αfunctions␈α
will␈αimmediately
␈↓ ↓H␈↓cause␈αthe␈α
termination␈αof␈α
the␈αcomputation.␈α No␈α
information␈αother␈α
than␈αthe␈αfact␈α
that␈α␈↓λB␈↓␈α
did␈αappear
␈↓ ↓H␈↓results␈α
from␈αsuch␈α
an␈αoccurrence.␈α
If␈α
we␈αthought␈α
of␈αthe␈α
evaluation␈α
of␈α␈↓λB␈↓␈α
as␈αresulting␈α
in␈α
a␈αdivergent
␈↓ ↓H␈↓computation,␈αthen␈αno␈αinformation␈αat␈αall␈αwould␈αbe␈αforthcoming.␈α In␈αreality,␈αa␈α
LISP␈αimplementation
␈↓ ↓H␈↓can␈α∞handle␈α∞many␈α∞computations␈α∞which␈α∞involve␈α∞␈↓λB␈↓.␈α∞The␈α∞computation␈α∞might␈α∞be␈α∞terminated␈α∂and␈α∞an
␈↓ ↓H␈↓error␈αprinted;␈α
in␈αan␈αinteractive␈α
implementation,␈αthe␈αuser␈α
might␈αbe␈αgiven␈α
an␈αopportunity␈α
to␈αcorrect
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 32␈↓␈αHowever␈αsome␈αlanguages␈αdo␈α
require␈αsome␈αkind␈αof␈αdeclaration␈α
to␈αthe␈αeffect␈αthat␈αa␈α
procedure␈αis
␈↓ ↓H␈↓recursive.
␈↓ ↓H␈↓␈↓π 33␈↓ called "puns" by C. Strachey
␈↓ ↓H␈↓␈↓↓1.8␈↓
∧A Respite 39␈↓
␈↓ ↓H␈↓the␈α∪error␈α∀and␈α∪have␈α∪the␈α∀computation␈α∪continue;␈α∪and␈α∀alas,␈α∪some␈α∪implementations␈α∀just␈α∪continue
␈↓ ↓H␈↓computation␈α⊗with␈α⊗some␈α⊗arbitrary␈α⊗piece␈α⊗of␈α⊗information␈α⊗produced␈α⊗by␈α⊗an␈α⊗excursion␈α⊗into␈α∃the
␈↓ ↓H␈↓subsconscious␈α∂of␈α∂LISP.␈α⊂Divergent␈α∂computations␈α∂cannot␈α⊂be␈α∂detected␈α∂in␈α⊂such␈α∂a␈α∂clear␈α⊂manner␈α∂and
␈↓ ↓H␈↓implementations␈α∞differ␈α∞in␈α∂their␈α∞handling␈α∞of␈α∞this␈α∂interpretation␈α∞of␈α∞␈↓λB␈↓.␈α∞ We␈α∂will␈α∞have␈α∞more␈α∂to␈α∞say
␈↓ ↓H␈↓about the implementation of ␈↓λB␈↓ in Section 6.23.
␈↓ ↓H␈↓Later,␈α⊗we␈α∃will␈α⊗motivate␈α⊗the␈α∃more␈α⊗traditional␈α∃studies␈α⊗of␈α⊗data␈α∃structures␈α⊗by␈α⊗considering␈α∃the
␈↓ ↓H␈↓implementations␈αof␈αLISP-related␈αlanguages.␈α
But␈αthe␈αpath␈αto␈αthose␈α
studies␈αis␈αat␈αleast␈α
as␈αimportant.
␈↓ ↓H␈↓On␈α
the␈α
way␈αwe␈α
will␈α
show␈α
that␈αwe␈α
can␈α
exploit␈αabstraction␈α
as␈α
a␈α
means␈αfor␈α
giving␈α
a␈αclear␈α
specification
␈↓ ↓H␈↓of␈α∂evaluation␈α∂of␈α∂LISP␈α∂expressions,␈α∂and␈α∂the␈α∂representational␈α∂techniques␈α∂we␈α∂will␈α∂use␈α⊂will␈α∂involve
␈↓ ↓H␈↓applications␈αof␈αabstract␈αdata␈αstructures.␈αA␈αmore␈αtangible␈αbenefit␈αshould␈αbe␈αan␈αincreased␈αawareness
␈↓ ↓H␈↓of␈α
the␈α
structure␈α
and␈α
behavior␈α
of␈α
programming␈α
languages,␈α
and␈α
the␈α
beginnings␈α
of␈α
a␈α
better␈α∞style␈α
of
␈↓ ↓H␈↓programming.
␈↓ ↓H␈↓Another␈α
part␈α
of␈α
our␈α
investigation␈αshould␈α
be␈α
to␈α
answer␈α
the␈αquestion␈α
"What␈α
is␈α
a␈α
data␈αstructure?".␈α
As
␈↓ ↓H␈↓we␈α⊂mentioned␈α⊂at␈α∂the␈α⊂beginning␈α⊂of␈α∂Section 1.6␈α⊂there␈α⊂is␈α∂a␈α⊂different␈α⊂characterization␈α⊂of␈α∂sequences
␈↓ ↓H␈↓which␈αwill␈αgive␈αa␈αdifferent␈αinterpretation␈αof␈αdata␈αstructures.␈αThe␈αstandard␈αmathematical␈αdefinition
␈↓ ↓H␈↓of a sequence is as a function from the integers to a particular domain.
␈↓ ↓H␈↓Thus a finite sequence ␈↓s␈↓ might be given as:
␈↓ ↓H␈↓␈↓ ∧m␈↓s␈↓ = ␈↓{<1, s␈↓β1␈↓>, <2, s␈↓β2␈↓>, ...<n, s␈↓βn␈↓>}
␈↓ ↓H␈↓To␈α⊂select␈α∂components␈α⊂of␈α∂␈↓s␈↓,␈α⊂we␈α∂use␈α⊂ordinary␈α∂function␈α⊂application:␈α∂␈↓s(i)␈↓ = ␈↓s␈↓βi␈↓.␈α⊂Indeed,␈α∂if␈α⊂you␈α∂have
␈↓ ↓H␈↓programmed␈αin␈αa␈αlanguage␈αwhich␈αhas␈αarray␈αconstructs,␈αyou␈αwill␈αrecognize␈α"application"␈αas␈αthe␈αstyle
␈↓ ↓H␈↓of notation used: A[3] selected the 3␈↓πrd␈↓ component for the array A.
␈↓ ↓H␈↓However␈α∂this␈α∞is␈α∂quite␈α∞different␈α∂from␈α∞what␈α∂we␈α∞did␈α∂in␈α∞the␈α∂section␈α∞on␈α∂sequences.␈α∞ For␈α∂example,␈α∞if
␈↓ ↓H␈↓␈↓↓(A, B, C)␈↓ is a sequence, ␈↓s␈↓, then in the new interpretation we should write:
␈↓ ↓H␈↓␈↓ ¬ ␈↓s␈↓ = ␈↓{<1, ␈↓↓A␈↓>, <2, ␈↓↓B␈↓>,<3, ␈↓↓C␈↓>}
␈↓ ↓H␈↓Thus␈α∂␈↓s(2)␈↓␈α⊂is␈α∂␈↓↓B␈↓,␈α⊂etc.␈α∂What␈α⊂has␈α∂happened␈α⊂is␈α∂that␈α⊂what␈α∂was␈α⊂previously␈α∂considered␈α⊂to␈α∂be␈α⊂a␈α∂data
␈↓ ↓H␈↓structure␈αhas␈αbecome␈αa␈αfunction,␈αand␈αthe␈αselector␈αfunctions␈αon␈αthe␈αdata␈αstructure␈αhave␈αnow␈αbecome
␈↓ ↓H␈↓static indices on the function. Or to make things more transparent:
␈↓ ↓H␈↓␈↓ ∧D␈↓s␈↓ = ␈↓{<␈↓αfirst␈↓, ␈↓↓A␈↓>, <␈↓αsecond␈↓, ␈↓↓B␈↓>,<␈↓αthird␈↓, ␈↓↓C␈↓>}
␈↓ ↓H␈↓Then␈α
we␈α
would␈α
write␈α
␈↓s(␈↓αfirst␈↓)␈↓␈α
rather␈α
than␈α
␈↓αfirst␈↓(s)␈↓␈↓π 34␈↓.␈α
This␈α
idea␈α
can␈α
easily␈α
be␈α
applied␈α∞to␈α
S-exprs
␈↓ ↓H␈↓and␈αtheir␈αfunctions.␈αIn␈αgraphical␈αterms␈αwe␈αare␈αrepresenting␈αthe␈αstructures␈αsuch␈αthat␈αthe␈αarcs␈αof␈αthe
␈↓ ↓H␈↓graph␈αare␈αlabeled␈αwith␈αthe␈αselector␈α
indices.␈αWith␈αL-trees␈αthe␈αlabeling␈αwas␈αimplicit:␈α
left-branch␈αwas
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 34␈↓␈α
G.␈α
Steele␈α
([Ste pc])␈α
reports␈α
that␈αPPL␈α
(Polymorphic␈α
Programming␈α
Language)␈α
at␈α
Harvard␈αlets␈α
you
␈↓ ↓H␈↓do this: ␈↓αcar[s]␈↓ and ␈↓αs[car]␈↓ both work.
␈↓ ↓H␈↓␈↓↓40 Symbolic expressions␈↓ 61.8␈↓
␈↓ ↓H␈↓␈↓αcar␈↓;␈α∂right-branch␈α∂was␈α∂␈↓αcdr␈↓.␈α∂ With␈α∂explicit␈α∂labels␈α⊂on␈α∂the␈α∂branches,␈α∂the␈α∂trees␈α∂need␈α∂not␈α⊂be␈α∂ordered.
␈↓ ↓H␈↓Several␈αlanguages␈αimplement␈αsuch␈αunordered␈αtrees;␈αthey␈αare␈αcalled␈α␈↓αstructure␈↓s␈αin␈αAlgol 68␈αand␈αEL1,
␈↓ ↓H␈↓and␈αcalled␈α␈↓αrecord␈↓s␈α
in␈αPascal.␈α Several␈α
formalisms␈αexploit␈αthis␈αview␈α
of␈αdata␈αstructures;␈α
in␈αparticular
␈↓ ↓H␈↓the␈α∞Vienna␈α∞Definition␈α∞Language ([Weg 72]),␈α
which␈α∞is␈α∞a␈α∞direct␈α
descendant␈α∞of␈α∞LISP,␈α∞represents␈α
its
␈↓ ↓H␈↓data in such a manner.
␈↓ ↓H␈↓What␈αthen␈α
is␈αa␈α
data␈αstructure?␈α
It␈αdepends␈α
on␈αhow␈αyou␈α
look␈αat␈α
it.␈αFor␈α
our␈αimmediate␈α
purposes␈αwe
␈↓ ↓H␈↓will␈α
try␈α
to␈α
remain␈α
intuitive␈αand␈α
informal.␈α
We␈α
will␈α
try␈α
to␈αcharacterize␈α
an␈α
abstract␈α
data␈α
structure␈αas␈α
a
␈↓ ↓H␈↓domain␈αand␈αa␈αcollection␈αof␈αassociated␈α
operations␈αand␈αcontrol␈αstructures.␈αThe␈αoperations␈αand␈α
control
␈↓ ↓H␈↓mechanisms␈α⊃should␈α⊃allow␈α⊃us␈α⊃to␈α⊃describe␈α⊃algorithms␈α⊃in␈α⊃a␈α⊃natural␈α⊃manner␈α⊃but␈α⊃should,␈α⊃if␈α⊃at␈α⊃all
␈↓ ↓H␈↓possible, remain representation independent.
␈↓ ↓H␈↓A␈α
few␈α
tricks␈α
were␈α
embedded␈αin␈α
the␈α
problem␈α
sets.␈α
Recall␈αproblem␈α
␈↓↓8␈↓␈α
on␈α
page 24.␈α
The␈αcomposition
␈↓ ↓H␈↓␈↓αatom[cons[␈α...]]␈↓␈αwill␈αalways␈αevaluate␈αto␈α␈↓
f␈↓␈α␈↓π 35␈↓␈αsince␈αthe␈αresult␈αof␈α␈↓αcons␈↓␈αis␈αalways␈αnon-atomic.␈α In␈α␈↓↓10␈↓,␈αwe
␈↓ ↓H␈↓used␈αatoms␈αwith␈αthe␈αsame␈αletter␈αstrings␈αas␈αpredicate␈αnames,␈α␈↓αATOM␈↓␈αand␈α␈↓αEQ␈↓.␈α ␈↓αATOM␈↓␈αand␈α␈↓αEQ␈↓␈αare
␈↓ ↓H␈↓perfectly␈αgood␈αatoms,␈αand␈αare␈α␈↓↓not␈↓␈αto␈αbe␈αconfused␈αwith␈αthe␈αLISP␈αpredicates.␈α Problem ␈↓↓16␈↓␈αshows␈α
that
␈↓ ↓H␈↓conditional expressions may appear within a functional composition.
␈↓ ↓H␈↓Notice␈αthat␈α␈↓αtwist␈↓␈αin␈αII␈αis␈αtotal␈αwhereas␈α␈↓αfindem␈↓␈αis␈αpartial.␈α ␈↓αfindem␈↓␈αis␈αpartial␈αsince␈α␈↓αy␈↓␈αmust␈α
be␈αatomic.
␈↓ ↓H␈↓Both␈αfunctions␈αbuild␈αnew␈αtrees:␈α␈↓αtwistem␈↓␈αreverses␈αleft-␈αand␈αright-branches␈αrecursively;␈α␈↓αfindem␈↓␈αbuilds
␈↓ ↓H␈↓a␈α
tree␈αwith␈α
the␈α
same␈αbranching␈α
structure␈α
as␈α␈↓αx␈↓,␈α
but␈α
the␈αterminal␈α
nodes␈α
contain␈α␈↓αT␈↓␈α
at␈α
the␈αpoints␈α
where
␈↓ ↓H␈↓the atom ␈↓αy␈↓ appears in the original tree, and ␈↓αNIL␈↓ otherwise.
␈↓ ↓H␈↓Be␈αclear␈αon␈αthe␈αdifference␈αbetween␈αthe␈αrepresentation␈α
of␈αthe␈αempty␈αlist:␈α␈↓αNIL␈↓,␈αand␈αthe␈αlist␈α
consisting
␈↓ ↓H␈↓of␈α␈↓αNIL␈↓:␈α
␈↓α(NIL)␈↓;␈αnote␈α
that␈α␈↓α(NIL)␈↓␈α
is␈αan␈α
abbreviation␈αfor␈α
␈↓α(NIL␈α.␈α
NIL)␈↓,␈αwhich␈α
certainly␈αis␈α
not␈α␈↓αNIL␈↓.
␈↓ ↓H␈↓List-notation␈α∞is␈α∞an␈α∞abbreviation␈α∂and␈α∞can␈α∞always␈α∞be␈α∞translated␈α∂back␈α∞into␈α∞a␈α∞S-expr,␈α∞but␈α∂not␈α∞every
␈↓ ↓H␈↓S-expr is the representation of a list.
␈↓ ↓H␈↓The distinction between ␈↓αconcat␈↓ and ␈↓αlist␈↓ is sometimes confusing:
␈↓ ↓H␈↓␈↓ ∧>␈↓αconcat[␈↓λα␈↓β1␈↓α; (␈↓λα␈↓β2␈↓α, ...␈↓λα␈↓βn␈↓α)]␈↓ is ␈↓α(␈↓λα␈↓β1␈↓α, ␈↓λα␈↓β2␈↓α, ... ␈↓λα␈↓βn␈↓α).
␈↓ ↓H␈↓α␈↓ ∧Klist[␈↓λα␈↓β1␈↓α;(␈↓λα␈↓β2␈↓α, ... ␈↓λα␈↓βn␈↓α)]␈↓ is ␈↓α(␈↓λα␈↓β1␈↓α (␈↓λα␈↓β2␈↓α ... ␈↓λα␈↓βn␈↓α))␈↓.
␈↓ ↓H␈↓So␈α␈↓αconcat␈↓␈αwill␈αadd␈αa␈αnew␈αelement␈αto␈αthe␈αfront␈αof␈αan␈αexisting␈αlist,␈αwhereas␈α␈↓αlist␈↓␈αwill␈αcreate␈αa␈αnew␈αlist
␈↓ ↓H␈↓whose elements will be the values of the arguments to ␈↓αlist␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 35␈↓␈α
If␈αit␈α
has␈αa␈α
value␈αat␈α
all!␈αIf␈α
the␈α
computation␈αof␈α
the␈αarguments␈α
to␈αthe␈α
␈↓αcons␈↓␈αdoes␈α
not␈α
terminate␈αor
␈↓ ↓H␈↓gives ␈↓λB␈↓ then we won't get ␈↓
f␈↓.
␈↓ ↓H␈↓␈↓↓1.9␈↓ λrBecoming an Expert 41␈↓
␈↓ ↓H␈↓␈↓ ¬*␈↓↓1.9 Becoming an Expert␈↓
␈↓ ↓H␈↓We␈α∂have␈α∂already␈α∂traced␈α∂the␈α∂development␈α∂of␈α∂a␈α∂few␈α∂LISP␈α∂algorithms,␈α∂and␈α∂we␈α∂have␈α∂given␈α⊂a␈α∂few
␈↓ ↓H␈↓programming␈αhints.␈αIt␈αis␈αtime␈αto␈αreinforce␈αthese␈αtentative␈αstarts␈αwith␈αa␈αmore␈αintensive␈αstudy␈αof␈αthe
␈↓ ↓H␈↓techniques␈αfor␈αwriting␈αgood␈αLISP␈αprograms.␈α This␈αsection␈αwill␈αspend␈αa␈αgood␈αdeal␈αof␈αtime␈αshowing
␈↓ ↓H␈↓different␈αstyles␈αof␈αdefinition,␈αgiving␈αhints␈α
about␈αhow␈αto␈αwrite␈αLISP␈αfunctions,␈αand␈α
increasing␈αyour
␈↓ ↓H␈↓familiarity␈αwith␈αLISP.␈α For␈αthose␈αof␈αyou␈αwho␈αare␈αimpatiently␈αwaiting␈αto␈αsee␈αsome␈α␈↓↓real␈↓␈αapplications
␈↓ ↓H␈↓of␈α
this␈α
programming␈α
language,␈αwe␈α
can␈α
only␈α
say␈α
"be␈αpatient".␈α
The␈α
next␈α
chapter␈α
␈↓↓will␈↓␈αdevelop␈α
several
␈↓ ↓H␈↓non-trivial␈α∩algorithms,␈α⊃but␈α∩what␈α⊃we␈α∩must␈α⊃do␈α∩first␈α⊃is␈α∩improve␈α⊃your␈α∩skills,␈α⊃even␈α∩at␈α⊃the␈α∩risk␈α⊃of
␈↓ ↓H␈↓worsening your disposition.
␈↓ ↓H␈↓First␈α
some␈α∞terminology␈α
is␈α∞appropriate:␈α
the␈α∞style␈α
of␈α∞definition␈α
which␈α∞we␈α
have␈α∞been␈α
using␈α∞is␈α
called
␈↓ ↓H␈↓␈↓↓definition by recursion␈↓. The basic components of such a definition are:
␈↓ ↓H␈↓␈↓ αh␈↓↓1.␈↓␈αA␈αbasis␈αcase:␈αwhat␈αto␈αcompute␈αas␈αvalue␈αfor␈αthe␈αfunction␈αin␈αone␈αor␈αmore␈αparticularly
␈↓ ↓H␈↓␈↓ αhsimple cases. A basis case is frequently referred to as a termination case.
␈↓ ↓H␈↓␈↓ REC␈↓
␈↓ ↓H␈↓␈↓ αh␈↓↓2.␈↓␈αA␈αgeneral␈αcase:␈αwhat␈αto␈αcompute␈αas␈αvalue␈αfor␈αa␈αfunction,␈αgiven␈αthe␈αvalues␈αof␈αone␈αor
␈↓ ↓H␈↓␈↓ αhmore previous computations on that function.
␈↓ ↓H␈↓You␈α_should␈α_compare␈α_the␈α_structure␈α_of␈α_a␈α_␈↓ REC␈↓-definition␈α_of␈α_a␈α_function␈α_with␈α_that␈α→of␈α_an
␈↓ ↓H␈↓␈↓ IND␈↓-definition␈α∞of␈α∞a␈α∞set␈α∞(see␈α∞␈↓ IND␈↓␈α∞on␈α∞page 3).␈α∞ Applications␈α∞of␈α∞␈↓ REC␈↓-definitions␈α∂are␈α∞particularly
␈↓ ↓H␈↓useful␈α∩in␈α∩computing␈α∩values␈α∩of␈α⊃a␈α∩function␈α∩defined␈α∩over␈α∩a␈α⊃set␈α∩which␈α∩has␈α∩been␈α∩defined␈α∩by␈α⊃an
␈↓ ↓H␈↓␈↓ IND␈↓-definition.␈α∂For␈α∂example,␈α∂assume␈α⊂that␈α∂we␈α∂have␈α∂defined␈α∂a␈α⊂set␈α∂␈↓A␈↓␈α∂using␈α∂␈↓ IND␈↓␈α∂then␈α⊂a␈α∂typical
␈↓ ↓H␈↓algorithm␈α
for␈α
computing␈α
a␈α
function␈α␈↓f␈↓␈α
over␈α
␈↓A␈↓␈α
would␈α
involve␈α
two␈αparts:␈α
first,␈α
an␈α
indication␈α
of␈αhow␈α
to
␈↓ ↓H␈↓compute␈α␈↓f␈↓␈αon␈αthe␈αbase␈αdomain␈αof␈α␈↓A␈↓,␈αand␈αsecond,␈αgiven␈αvalues␈αfor␈αsome␈αelements␈αof␈α␈↓A␈↓␈αsay␈α␈↓a␈↓β1␈↓, ...,␈↓a␈↓βn␈↓,
␈↓ ↓H␈↓use␈α␈↓ IND␈↓␈α
to␈αgenerate␈α
a␈αnew␈αelement␈α
␈↓a␈↓;␈αthen␈α
specify␈αthe␈α
value␈αof␈α␈↓f(a)␈↓␈α
as␈αa␈α
function␈αof␈α
the␈αknown
␈↓ ↓H␈↓values of ␈↓f(a␈↓β1␈↓)␈↓, ..., ␈↓f(a␈↓βn␈↓)␈↓. That is exactly the structure of ␈↓ REC␈↓.
␈↓ ↓H␈↓Here␈α
is␈α
another␈α
attribute␈α
of␈α
␈↓ IND␈↓-definitions:␈α
Suppose␈αwe␈α
have␈α
defined␈α
a␈α
set␈α
␈↓A␈↓␈α
using␈α
␈↓ IND␈↓,␈αand
␈↓ ↓H␈↓we wish to prove that a certain property ␈↓ P␈↓ holds for every element of ␈↓A␈↓. We need only show that:
␈↓ ↓H␈↓␈↓ αh␈↓↓1.␈↓ ␈↓ P␈↓ holds for every element of the base domain of ␈↓A␈↓.
␈↓ ↓H␈↓␈↓ PRF␈↓
␈↓ ↓H␈↓␈↓ αh␈↓↓2.␈↓␈αUsing␈αthe␈αtechnique␈αwe␈αelaborated␈αin␈αdefining␈αthe␈αfunction␈α␈↓f␈↓␈αabove,␈αif␈αwe␈αcan␈αshow
␈↓ ↓H␈↓␈↓ αhthat␈α
␈↓ P␈↓␈α
holds␈α
for␈α
the␈α
new␈α
element␈α
perhaps␈α
relying␈α
on␈α
proofs␈α
of␈α
␈↓ P␈↓␈α
for␈αsub-elements,␈α
then
␈↓ ↓H␈↓␈↓ αhwe should have a convincing argument that ␈↓ P␈↓ holds over ␈↓↓all␈↓ of ␈↓A␈↓.
␈↓ ↓H␈↓This␈α⊂proof␈α∂technique␈α⊂is␈α∂a␈α⊂generalization␈α⊂of␈α∂a␈α⊂common␈α∂technique␈α⊂for␈α∂proving␈α⊂properties␈α⊂of␈α∂the
␈↓ ↓H␈↓integers. In that context it is called mathematical induction.
␈↓ ↓H␈↓␈↓↓42 Symbolic expressions␈↓ 71.9␈↓
␈↓ ↓H␈↓We␈αare␈αseeing␈αan␈αinteresting␈αparallel␈αbetween␈αinductive␈αdefinitions␈αof␈αsets,␈αrecursive␈α
definitions␈αof
␈↓ ↓H␈↓functions,␈α∩and␈α∪proofs␈α∩by␈α∩induction.␈α∪ As␈α∩we␈α∩proceed,␈α∪we␈α∩will␈α∩exploit␈α∪various␈α∩aspects␈α∪of␈α∩these
␈↓ ↓H␈↓interrelationships.␈α∂ However␈α∂our␈α∂task␈α∂at␈α∂hand␈α⊂is␈α∂more␈α∂mundane:␈α∂to␈α∂develop␈α∂facility␈α⊂at␈α∂applying
␈↓ ↓H␈↓␈↓ REC␈↓␈α∂to␈α⊂define␈α∂functions␈α∂over␈α⊂the␈α∂␈↓ IND␈↓-domains␈α⊂of␈α∂symbolic␈α∂expressions,␈α⊂␈↓ S␈↓,␈α∂and␈α⊂of␈α∂sequences,
␈↓ ↓H␈↓␈↓ Seq␈↓.
␈↓ ↓H␈↓First␈αlet's␈αverify␈αthat␈αthe␈α
functions␈αwe␈αhave␈αconstructed␈αso␈α
far␈αdo␈αindeed␈αsatisfy␈α␈↓ REC␈↓.␈α
Recall␈αour
␈↓ ↓H␈↓example␈αof␈α␈↓αequal␈↓␈αon␈αpage 23.␈αThe␈αbasis␈αcase␈αinvolves␈αa␈αcalculation␈αon␈αmembers␈αof␈α
␈↓<atom>␈↓;␈αthere
␈↓ ↓H␈↓we␈α
rely␈α
on␈α␈↓αeq␈↓␈α
to␈α
distinguish␈α
between␈αdistinct␈α
atoms.␈α
The␈α
question␈αof␈α
equality␈α
for␈α
two␈αnon-atomic
␈↓ ↓H␈↓S-exprs␈α
was␈αrecast␈α
as␈αa␈α
question␈αof␈α
equality␈αfor␈α
their␈α␈↓αcar␈↓s␈α
and␈α␈↓αcdr␈↓s.␈α
But␈αthat␈α
too,␈αis␈α
proper␈αsince␈α
the
␈↓ ↓H␈↓constructed object is manufactured by ␈↓αcons␈↓, and ␈↓αcar␈↓ and ␈↓αcdr␈↓ of that object select the components.
␈↓ ↓H␈↓Similar␈α∞justification␈α∂for␈α∞␈↓αlength␈↓␈α∂on␈α∞page 30␈α∂can␈α∞be␈α∂given.␈α∞ There␈α∂the␈α∞domain␈α∂is␈α∞␈↓ Seq␈↓.␈α∂The␈α∞base
␈↓ ↓H␈↓domain␈αis␈αthe␈αempty␈α
sequence,␈αand␈α␈↓αlength␈↓␈αis␈αdefined␈α
to␈αgive␈α␈↓α0␈↓␈αin␈αthat␈α
case.␈αThe␈αgeneral␈αcase␈αin␈α
the
␈↓ ↓H␈↓recursion␈α
comes␈α
from␈α
the␈α∞␈↓ IND␈↓-definition␈α
of␈α
a␈α
sequence␈↓π 36␈↓.␈α
Given␈α∞a␈α
sequence␈α
␈↓↓s␈↓,␈α
we␈α
made␈α∞a␈α
new
␈↓ ↓H␈↓sequence␈αby␈αadding␈αa␈αsequence␈αelement␈αto␈αthe␈α
front␈αof␈α␈↓↓s␈↓.␈αAgain␈αthe␈αcomputation␈αof␈α␈↓αlength␈↓␈α
parallels
␈↓ ↓H␈↓this␈α
construction,␈α
saying␈α
that␈α∞the␈α
length␈α
of␈α
this␈α∞new␈α
sequence␈α
is␈α
one␈α∞more␈α
than␈α
the␈α
length␈α∞of␈α
the
␈↓ ↓H␈↓sequence ␈↓↓s␈↓.
␈↓ ↓H␈↓For a more traditional example consider the factorial function, n!.
␈↓ ↓H␈↓␈↓↓1.␈↓ The function is defined for non-negative integers.
␈↓ ↓H␈↓␈↓↓2.␈↓ The value of the function for 0 is 1.
␈↓ ↓H␈↓␈↓↓3␈↓. Otherwise the value of n! is n times the value of (n-1)!.
␈↓ ↓H␈↓It should now be clear how to write a LISP program for the factorial function:
␈↓ ↓H␈↓α␈↓ β|fact[n] <= [eq[n;0] → 1; ␈↓
t␈↓α → times[n;fact[sub1[n]]]] ␈↓π 37␈↓α
␈↓ ↓H␈↓The␈αimplication␈αis␈α
that␈αit␈αis␈α
easier␈αto␈αcompute␈α
(n-1)!␈αthan␈αto␈α
compute␈αn!.␈αBut␈α
that␈αtoo␈αis␈α
in␈αaccord
␈↓ ↓H␈↓with our construction of the integers using the successor function.
␈↓ ↓H␈↓These␈α∩examples␈α∩are␈α∩typical␈α∩of␈α∩LISP's␈α∩recursive␈α∩definitions.␈α∩ The␈α∩body␈α∩of␈α∩the␈α∩definition␈α∩is␈α∩a
␈↓ ↓H␈↓conditional␈αexpression;␈αthe␈αfirst␈αfew␈αbranches␈αinvolve␈αspecial␈αcases,␈αcalled␈α
␈↓↓termination␈αconditions␈↓.
␈↓ ↓H␈↓Then␈αthe␈αremainder␈αof␈αthe␈αconditional␈αcovers␈αthe␈αgeneral␈αcase--␈αwhat␈αto␈αdo␈αif␈αthe␈αargument␈αto␈αthe
␈↓ ↓H␈↓function is not one of the special cases.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 36␈↓␈α∩Note␈α∩(page 26)␈α∩that␈α∪we␈α∩didn't␈α∩give␈α∩an␈α∩explicit␈α∪␈↓ IND␈↓-definition,␈α∩but␈α∩rather␈α∩a␈α∩set␈α∪of␈α∩BNF
␈↓ ↓H␈↓equations. The reader should supply the explicit definition.
␈↓ ↓H␈↓α␈↓π 37␈↓α times␈↓ is a LISP function which performs multiplication, and ␈↓αsub1␈↓ subtracts ␈↓α1␈↓ from its argument.
␈↓ ↓H␈↓␈↓↓1.9␈↓ λrBecoming an Expert 43␈↓
␈↓ ↓H␈↓Notice␈α⊂that␈α⊂␈↓αfact␈↓␈α⊂is␈α⊂a␈α⊂partial␈α⊂function,␈α⊂defined␈α⊂only␈α⊂for␈α⊂non-negative␈α⊂integers.␈α⊂When␈α⊂writing␈α⊂or
␈↓ ↓H␈↓reading␈α∂LISP␈α∂definitions␈α∂pay␈α∂particular␈α∂attention␈α∂to␈α∞the␈α∂domain␈α∂of␈α∂definition␈α∂and␈α∂the␈α∂range␈α∞of
␈↓ ↓H␈↓values produced. The following general hints should also be useful:
␈↓ ↓H␈↓␈↓↓1␈↓.␈α∀ Is␈α∪the␈α∀algorithm␈α∪to␈α∀be␈α∪a␈α∀LISP␈α∪function␈α∀or␈α∪predicate?␈α∀This␈α∪information␈α∀can␈α∪be␈α∀used␈α∪to
␈↓ ↓H␈↓double-check␈α∩uses␈α∩of␈α∩the␈α∩definition.␈α∩Don't␈α∪use␈α∩a␈α∩predicate␈α∩where␈α∩a␈α∩S-expr-valued␈α∪function␈α∩is
␈↓ ↓H␈↓expected; and don't use an S-expr-valued function where a list-value is expected.
␈↓ ↓H␈↓␈↓↓2␈↓.␈α Are␈αthere␈α
restrictions␈αon␈αthe␈αargument␈α
positions?␈αFor␈αexample,␈αmust␈α
some␈αof␈αthe␈α
arguments␈αbe
␈↓ ↓H␈↓truth values? Similar consistency checking as in ␈↓↓1␈↓ can be done with this information.
␈↓ ↓H␈↓␈↓↓3␈↓.␈α∂ Are␈α∂the␈α∞termination␈α∂conditions␈α∂compatible␈α∂with␈α∞the␈α∂restrictions␈α∂on␈α∂the␈α∞arguments?␈α∂ If␈α∂it␈α∂is␈α∞a
␈↓ ↓H␈↓recursion␈αon␈α
lists,␈αcheck␈αfor␈α
the␈αempty␈α
list;␈αif␈αit␈α
is␈αa␈α
recursion␈αof␈αarbitrary␈α
S-exprs,␈αthen␈α
check␈αfor
␈↓ ↓H␈↓the appearance of an atom.
␈↓ ↓H␈↓␈↓↓4␈↓.␈α Whenever␈αa␈αfunction␈αcall␈αis␈αmade␈αwithin␈αthe␈αdefinition,␈αare␈αall␈αthe␈αrestrictions␈αon␈αthat␈αfunction
␈↓ ↓H␈↓satisfied?
␈↓ ↓H␈↓␈↓↓5␈↓.␈α Don't␈αtry␈αto␈αdo␈αtoo␈αmuch.␈αTry␈αto␈αbe␈αlazy.␈αThere␈αis␈αusually␈αa␈αvery␈αsimple␈αtermination␈αcase.␈αIf␈α
the
␈↓ ↓H␈↓termination␈α⊃case␈α⊃looks␈α⊃messy,␈α∩there␈α⊃is␈α⊃probably␈α⊃something␈α∩wrong␈α⊃with␈α⊃your␈α⊃conception␈α∩of␈α⊃the
␈↓ ↓H␈↓program.␈α
If␈αthe␈α
general␈αcase␈α
looks␈αmessy,␈α
then␈α
write␈αsome␈α
subfunctions␈αto␈α
perform␈αthe␈α
brunt␈αof␈α
the
␈↓ ↓H␈↓calculation.
␈↓ ↓H␈↓Apply␈α
the␈αsuggestions␈α
when␈αwriting␈α
any␈αsubfunction.␈α
When␈αyou␈α
are␈αfinished,␈α
no␈αfunction␈α
will␈αdo
␈↓ ↓H␈↓very␈α
much,␈α
but␈α
the␈α
net␈α
effect␈α
of␈α
all␈α
the␈α
functions␈α
acting␈α
in␈α
concert␈α
is␈α
a␈α
solution␈α
to␈α
your␈α
problem.
␈↓ ↓H␈↓That is part of the mystique of recursive programming.
␈↓ ↓H␈↓As␈α
you␈α
may␈α
have␈αdiscovered,␈α
the␈α
real␈α
difficulty␈α
in␈αprogramming␈α
is␈α
writing␈α
your␈α
own␈αprograms.␈α
But
␈↓ ↓H␈↓who␈αsays␈αprogramming␈αis␈αeasy?␈αLISP␈αat␈αleast␈αmakes␈αsome␈αof␈αyour␈αdecisions␈αeasy.␈αIts␈αconstructs␈αare
␈↓ ↓H␈↓particularly␈α⊂frugal.␈α⊂So␈α⊂far␈α⊂there␈α∂is␈α⊂only␈α⊂␈↓↓one␈↓␈α⊂way␈α⊂to␈α∂write␈α⊂a␈α⊂non-trivial␈α⊂algorithm␈α⊂in␈α⊂LISP:␈α∂use
␈↓ ↓H␈↓recursion.␈α
The␈α
structure␈α
of␈α
the␈α
program␈α
flows␈α∞like␈α
that␈α
of␈α
an␈α
inductive␈α
argument.␈α
Find␈α∞the␈α
right
␈↓ ↓H␈↓induction␈α
hypothesis␈α
and␈α
the␈α
inductive␈αproof␈α
is␈α
easy;␈α
find␈α
the␈αright␈α
structure␈α
on␈α
which␈α
to␈αrecur␈α
and
␈↓ ↓H␈↓recursive␈α
programming␈α
is␈α∞easy.␈α
It's␈α
easier␈α∞to␈α
begin␈α
with␈α
unary␈α∞functions;␈α
then␈α
there's␈α∞no␈α
question
␈↓ ↓H␈↓about␈α
which␈α
argument␈α
is␈α
to␈αbe␈α
decomposed.␈α
The␈α
only␈α
decision␈αis␈α
how␈α
to␈α
terminate␈α
the␈αrecursion.␈α
If
␈↓ ↓H␈↓the␈α
argument␈α
is␈α
an␈α
S-expr␈αwe␈α
typically␈α
terminate␈α
on␈α
the␈α
occurrence␈αof␈α
an␈α
atom.␈α
If␈α
the␈α
argument␈αis␈α
a
␈↓ ↓H␈↓list, then terminate on ␈↓α( )␈↓. If the argument is a number then terminate on zero.
␈↓ ↓H␈↓Consider␈α∀a␈α∪slightly␈α∀more␈α∪complicated␈α∀arithmetical␈α∪example,␈α∀the␈α∪Fibonacci␈α∀sequence:␈α∪0, 1, 1, 2,
␈↓ ↓H␈↓3, 5, 8, ... . This sequence can be characterized by the following recurrence relation:
␈↓ ↓H␈↓␈↓ ε f(0) = 0
␈↓ ↓H␈↓␈↓ ε f(1) = 1
␈↓ ↓H␈↓␈↓ ¬Wf(n) = f(n-1)+f(n-2);
␈↓ ↓H␈↓␈↓↓44 Symbolic expressions␈↓ 71.9␈↓
␈↓ ↓H␈↓The translation to a LISP function is easy:
␈↓ ↓H␈↓α␈↓ β8fib[n] <=␈↓ ∧8[eq[n;0] → 0;
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧8 eq[n;1] → 1;
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧8 ␈↓
t␈↓α → plus[fib[sub1[n]];fib[sub1[sub1[n]]]]]
␈↓ ↓H␈↓where ␈↓αplus␈↓ is a representation of the mathematical function, ␈↓α+␈↓.
␈↓ ↓H␈↓A␈α∂few␈α∂additional␈α∂points␈α∂can␈α∂be␈α∂made␈α⊂here.␈α∂Notice␈α∂that␈α∂an␈α∂evaluation␈α∂scheme␈α∂may␈α⊂imply␈α∂many
␈↓ ↓H␈↓duplicate␈αcomputations.␈α For␈αexample,␈αcomputation␈αof␈α␈↓αfib[5]␈↓␈αrequires␈αthe␈αcomputation␈αof␈α␈↓αfib[4]␈↓␈αand
␈↓ ↓H␈↓␈↓αfib[3]␈↓.␈α∞ But␈α∞within␈α
the␈α∞calculation␈α∞of␈α
␈↓αfib[4]␈↓␈α∞we␈α∞again␈α∞calculate␈α
␈↓αfib[3]␈↓,␈α∞etc.␈α∞ It␈α
would␈α∞be␈α∞nice␈α∞if␈α
we
␈↓ ↓H␈↓could␈α
restructure␈α
the␈α
definition␈α
of␈α
the␈α
function␈α∞␈↓αfib␈↓␈α
to␈α
stop␈α
this␈α
extra␈α
computation␈↓π 38␈↓.␈α
Since␈α∞we␈α
␈↓↓do␈↓
␈↓ ↓H␈↓wish to run programs on a machine we should give some attention to efficiency␈↓π 39␈↓.
␈↓ ↓H␈↓We␈αwill␈αdefine␈αanother␈αfunction,␈αcalled␈α␈↓αfib␈↓λ'␈↓,␈αon␈αthree␈αvariables␈α␈↓αx␈↓,␈α␈↓αy␈↓,␈αand␈α␈↓αn␈↓.␈αThe␈αvariables,␈α␈↓αx␈↓␈αand␈α␈↓αy␈↓,
␈↓ ↓H␈↓will be used to carry the partial computations. Consider:
␈↓ ↓H␈↓α␈↓ ¬Lfib␈↓β1␈↓α[n] <= fib␈↓λ'␈↓α[n;0;1]
␈↓ ↓H␈↓α␈↓ βHfib␈↓λ'␈↓α[n;x;y] <=␈↓ ¬λ[eq[n;0] → x;
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬λ ␈↓
t␈↓α → fib␈↓λ'␈↓α[sub1[n];plus[x;y];x]]
␈↓ ↓H␈↓This␈αexample␈α
is␈αcomplicated␈α
enough␈αto␈αwarrant␈α
closer␈αexamination.␈α
The␈αinitial␈α
call,␈α␈↓αfib␈↓β1␈↓α[n]␈↓,␈αhas␈α
the
␈↓ ↓H␈↓effect␈αof␈αcalling␈α␈↓αfib␈↓λ'␈↓␈αwith␈α␈↓αx␈↓␈αinitialized␈αto␈α␈↓α0␈↓␈αand␈αwith␈α␈↓αy␈↓␈αinitialized␈αto␈α␈↓α1␈↓.␈αThe␈αcalls␈αon␈α␈↓αfib␈↓λ'␈↓␈αwithin␈αthe
␈↓ ↓H␈↓body␈α∂of␈α∞the␈α∂definition,␈α∂say␈α∞the␈α∂i␈↓πth␈↓␈α∂such␈α∞recursive␈α∂call,␈α∂has␈α∞the␈α∂effect␈α∂of␈α∞saving␈α∂the␈α∂i␈↓πth␈↓␈α∞Fibonacci
␈↓ ↓H␈↓number in ␈↓αx␈↓ and the i-1␈↓πst␈↓ in ␈↓αy␈↓.
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓α␈↓ ∧Hfib␈↓β1␈↓α[4]␈↓ ¬(= fib␈↓λ'␈↓α[4;0;1]
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬(= fib␈↓λ'␈↓α[3;1;0]
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬(= fib␈↓λ'␈↓α[2;1;1]
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬(= fib␈↓λ'␈↓α[1;2;1]
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬(= fib␈↓λ'␈↓α[0;3;2]
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬(= 3
␈↓ ↓H␈↓Functions␈α
like␈α
␈↓αfib␈↓λ'␈↓,␈α
used␈αto␈α
help␈α
␈↓αfib␈↓β1␈↓,␈α
are␈αcalled␈α
"help functions"␈α
or␈α
␈↓↓auxiliary functions␈↓;␈αvariables
␈↓ ↓H␈↓like␈α∂␈↓αx␈↓␈α∂and␈α∂␈↓αy␈↓␈α∂in␈α∂␈↓αfib␈↓λ'␈↓␈α∂are␈α⊂called␈α∂␈↓↓accumulators␈↓ ([Moor 74]),␈α∂since␈α∂they␈α∂are␈α∂used␈α∂to␈α⊂accumulate␈α∂the
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 38␈↓␈α⊂An␈α⊂alternative␈α⊂solution␈α⊂is␈α⊂to␈α⊂supply␈α⊃a␈α⊂different␈α⊂evaluation␈α⊂scheme␈α⊂which␈α⊂might␈α⊂be␈α⊃able␈α⊂to
␈↓ ↓H␈↓remember previously calculated results. [Got 74].
␈↓ ↓H␈↓␈↓π 39␈↓␈αFor␈αthose␈αreaders␈αwith␈αsome␈αprogramming␈αexperience,␈αthe␈αsolution␈αmay␈αappear␈αeasy:␈αassign␈αthe
␈↓ ↓H␈↓partial␈αcomputations␈αto␈αtemporary␈αvariables.␈α The␈αproblem␈αhere␈αis␈αthat␈αour␈αcurrent␈αsubset␈αof␈αLISP
␈↓ ↓H␈↓doesn't contain assignment.
␈↓ ↓H␈↓␈↓↓1.9␈↓ λrBecoming an Expert 45␈↓
␈↓ ↓H␈↓partial␈α∂computations.␈α∂ The␈α∂technique␈α∂of␈α∂using␈α∞auxiliary␈α∂functions␈α∂and␈α∂accumulators␈α∂can␈α∂also␈α∞be
␈↓ ↓H␈↓applied␈α∂to␈α⊂the␈α∂factorial␈α⊂example.␈α∂When␈α∂viewed␈α⊂computationally,␈α∂the␈α⊂resulting␈α∂definition␈α⊂will␈α∂be
␈↓ ↓H␈↓more efficient, though the gain in efficiency is not as apparent as that in the Fibonacci example ␈↓π 40␈↓.
␈↓ ↓H␈↓Thus:
␈↓ ↓H␈↓α␈↓ ¬Efact␈↓β1␈↓α[n] <= fact␈↓λ'␈↓α[n;1];
␈↓ ↓H␈↓α␈↓ βnfact␈↓λ'␈↓α[n;x] <= [eq[n;0] → x; ␈↓
t␈↓α → fact␈↓λ'␈↓α[sub1[n];times[n;x]]]
␈↓ ↓H␈↓It␈αappears␈αthat␈αthe␈αpairs␈α␈↓αfact,␈αfact␈↓β1␈↓␈αand␈α␈↓αfib,␈αfib␈↓β1␈↓␈αare␈αequivalent.␈αPerhaps␈αwe␈αshould␈αprove␈αthat␈αthis
␈↓ ↓H␈↓is␈αso.␈α We␈αpresented␈αthe␈αcrucial␈αideas␈αfor␈αthe␈αproof␈αin␈αthe␈αdiscussion␈αon␈αpage 41␈αconcerning␈α␈↓ IND␈↓,
␈↓ ↓H␈↓␈↓ REC␈↓ and ␈↓ PRF␈↓. We shall examine the question of proofs of equivalence in Section 2.9.
␈↓ ↓H␈↓Auxiliary functions are also applicable to LISP functions defined over S-exprs:
␈↓ ↓H␈↓α␈↓ βnlength[n] <= [null[n] → 0; ␈↓
t␈↓α → add1[length[rest[n]]]] ␈↓π 41␈↓α
␈↓ ↓H␈↓α␈↓ ¬(length␈↓β1␈↓α[n] <= length␈↓λ'␈↓α[n;0]
␈↓ ↓H␈↓α␈↓ βblength␈↓λ'␈↓α[n;x] <= [null[n] → x; ␈↓
t␈↓α → length␈↓λ'␈↓α[rest[n];add1[x]]]
␈↓ ↓H␈↓α␈↓and again it appears that ␈↓αlength␈↓ is equivalent to ␈↓αlength␈↓β1␈↓.
␈↓ ↓H␈↓So␈αfar␈αour␈αexamples␈αhave␈αeither␈αbeen␈αnumerical␈αor␈αhave␈αbeen␈αpredicates.␈α Predicates␈αonly␈αrequire
␈↓ ↓H␈↓traversing␈α∂existing␈α∞S-exprs;␈α∂certainly␈α∂we␈α∞will␈α∂want␈α∞to␈α∂write␈α∂algorithms␈α∞which␈α∂build␈α∂new␈α∞S-exprs.
␈↓ ↓H␈↓Consider␈α
the␈αproblem␈α
of␈αwriting␈α
a␈αLISP␈α
algorithm␈αto␈α
reverse␈αa␈α
list␈α␈↓αx␈↓.␈α
There␈αis␈α
a␈α
simple␈αinformal
␈↓ ↓H␈↓computation:␈α
take␈α
elements␈α
from␈α
the␈α
front␈αof␈α
␈↓αx␈↓␈α
and␈α
put␈α
them␈α
onto␈αthe␈α
front␈α
of␈α
a␈α
new␈α
list␈α␈↓αy␈↓.␈α
Initially,
␈↓ ↓H␈↓␈↓αy␈↓ should be ␈↓α( )␈↓ and the process should terminate when ␈↓αx␈↓ is empty.
␈↓ ↓H␈↓For example, reversal of the list ␈↓α(A B C D)␈↓ would produce the sequence:
␈↓ ↓H␈↓α␈↓ ¬8x␈↓ πHy
␈↓ ↓H␈↓α␈↓ ¬8(A B C D)␈↓ πH( )
␈↓ ↓H␈↓α␈↓ ¬8(B C D)␈↓ πH(A)
␈↓ ↓H␈↓α␈↓ ¬8(C D)␈↓ πH(B A)
␈↓ ↓H␈↓α␈↓ ¬8(D)␈↓ πH(C B A)
␈↓ ↓H␈↓α␈↓ ¬8( )␈↓ πH(D C B A)
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 40␈↓␈αThe␈α␈↓αfib␈↓β1␈↓␈αexample␈α
improves␈αefficiency␈αmostly␈αby␈α
calculating␈αfewer␈αintermediate␈αresults.␈αThe␈α
gain
␈↓ ↓H␈↓in␈αthe␈α␈↓αfact␈↓β1␈↓␈αexample␈αis␈αinvolved␈αwith␈αthe␈αmachinery␈αnecessary␈αto␈αactually␈αexecute␈αthe␈αprogram:␈αthe
␈↓ ↓H␈↓run-time␈α∂environment,␈α∂if␈α∂you␈α∂wish.␈α∂We␈α⊂will␈α∂discuss␈α∂this␈α∂when␈α∂we␈α∂talk␈α∂about␈α⊂implementation␈α∂of
␈↓ ↓H␈↓LISP in Chapter 6. The whole question of: "what is efficient?" is open to discussion.
␈↓ ↓H␈↓α␈↓π 41␈↓α add1[x] <= x+1
␈↓ ↓H␈↓␈↓↓46 Symbolic expressions␈↓ 71.9␈↓
␈↓ ↓H␈↓What␈α∞follows␈α
is␈α∞␈↓αreverse␈↓,␈α
where␈α∞we␈α
use␈α∞a␈α
sub-function␈α∞␈↓αrev␈↓λ'␈↓␈α
to␈α∞do␈α
the␈α∞hard␈α
work␈α∞and␈α∞perform␈α
the
␈↓ ↓H␈↓initialization with the second argument to ␈↓αrev␈↓λ'␈↓.
␈↓ ↓H␈↓α␈↓ ¬:reverse[x] <= rev␈↓λ'␈↓α[x;( )]
␈↓ ↓H␈↓α␈↓ βWrev␈↓λ'␈↓α[x;y] <= [null[x] → y; ␈↓
t␈↓α → rev␈↓λ'␈↓α[rest[x];concat[first[x];y]]]
␈↓ ↓H␈↓This␈α
␈↓αreverse␈↓␈αfunction␈α
builds␈αup␈α
the␈αnew␈α
list␈α
by␈α␈↓αconcat␈↓-ing␈α
the␈αelements␈α
onto␈αthe␈α
second␈αargument␈α
of
␈↓ ↓H␈↓␈↓αrev␈↓λ'␈↓α␈↓.␈αSince␈α␈↓αy␈↓␈αwas␈αinitialized␈αto␈α␈↓α( )␈↓␈αwe␈αare␈αassured␈αthat␈αthe␈αresulting␈αconstruct␈αwill␈αbe␈αa␈αlist.␈α We␈αwill
␈↓ ↓H␈↓see a "direct" definition of the reversing function in a moment.
␈↓ ↓H␈↓Construction␈α
is␈α
usually␈α
not␈α∞quite␈α
so␈α
straightforward.␈α
Suppose␈α∞we␈α
require␈α
a␈α
LISP␈α∞function␈α
named
␈↓ ↓H␈↓␈↓αappend␈↓␈α
of␈α
two␈αlist␈α
arguments,␈α
␈↓αx␈↓␈αand␈α
␈↓αy␈↓,␈α
which␈αis␈α
to␈α
return␈α
a␈αnew␈α
list␈α
which␈αhas␈α
␈↓αx␈↓␈α
appended␈αonto␈α
the
␈↓ ↓H␈↓front of ␈↓αy␈↓. For example:
␈↓ ↓H␈↓α␈↓ ∧Sappend[(A B D);(C E)] = (A B D C E)
␈↓ ↓H␈↓α␈↓ ∧>append[A;(B C)] ␈↓ = ␈↓λB␈↓ since ␈↓αA␈↓ is not a list.
␈↓ ↓H␈↓␈↓ βu␈↓αappend[(A B C);( )] = append[( );(A B C)] = (A B C)
␈↓ ↓H␈↓␈↓αappend␈↓␈αis␈αa␈αpartial␈αfunction;␈αit␈αshould␈αbe␈αdefined␈αby␈αrecursion,␈αbut␈αrecursion␈αon␈αwhich␈αargument?
␈↓ ↓H␈↓If␈αeither␈αargument␈αis␈α␈↓α( )␈↓␈αthen␈αthe␈αvalue␈αgiven␈αby␈α␈↓αappend␈↓␈αis␈αthe␈αother␈αargument.␈αThe␈αnext␈αsimplest
␈↓ ↓H␈↓case␈αis␈αa␈αone-element␈αlist;␈αif␈αexactly␈αone␈αof␈α␈↓αx␈↓␈αor␈α␈↓αy␈↓␈αis␈αa␈αsingleton␈αhow␈αdoes␈αthat␈αhelp␈αus␈αdiscover␈αthe
␈↓ ↓H␈↓recurrence␈αrelation␈α
for␈αappending?␈αIt␈α
doesn't␈αhelp␈α
much␈αif␈α␈↓αy␈↓␈α
is␈αa␈α
singleton;␈αbut␈αif␈α
␈↓αx␈↓␈αis␈α
a␈αsingleton,
␈↓ ↓H␈↓then ␈↓αappend␈↓ could give:
␈↓ ↓H␈↓␈↓ ¬+␈↓αconcat[first[x];y]␈↓ as result.
␈↓ ↓H␈↓So recursion on ␈↓αx␈↓ is likely. The definition now follows.
␈↓ ↓H␈↓␈↓ β%␈↓αappend[x;y] <= [null[x] → y; ␈↓
t␈↓α → concat[first[x];append[rest[x];y]]].␈↓
␈↓ ↓H␈↓Notice␈αthat␈αthe␈αconstruction␈αof␈αthe␈αresult␈αis␈α
a␈αbit␈αmore␈αobscure␈αthan␈αthat␈αinvolved␈αin␈α
␈↓αreverse␈↓.␈αThe
␈↓ ↓H␈↓construction has to "wait" until we have seen the end of the list ␈↓αx␈↓. For example:
␈↓ ↓H␈↓α␈↓ αXappend[(A B C);(D E F)]␈↓ ¬8= concat[A;append[(B C);(D E F)]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬8= concat[A;concat[B;append[(C);(D E F)]]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬8= concat[A;concat[B;concat[C;append[( );(D E F)]]]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬8= concat[A;concat[B;concat[C;(D E F)]]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬8= concat[A;concat[B;(C D E F)]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬8= concat[A;(B C D E F)]
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬8= (A B C D E F)
␈↓ ↓H␈↓We␈α
are␈αassured␈α
of␈αconstructing␈α
a␈αlist␈α
here␈αbecause␈α
␈↓αy␈↓␈α
is␈αa␈α
list␈αand␈α
we␈αare␈α
␈↓αconcat␈↓-ing␈αonto␈α
the␈αfront␈α
of
␈↓ ↓H␈↓it.␈αLISP␈αfunctions␈αwhich␈αare␈αto␈αconstruct␈αlist␈αoutput␈αby␈α␈↓αconcat␈↓-ing␈α␈↓↓must␈↓␈α␈↓αconcat␈↓␈αonto␈αthe␈αfront␈αof␈αan
␈↓ ↓H␈↓existing␈α␈↓↓list␈↓.␈αThat␈αlist␈αmay␈αbe␈αeither␈αnon-empty␈α
or␈αthe␈αempty␈αlist,␈α␈↓α( )␈↓.␈αThis␈αis␈αwhy␈α
the␈αtermination
␈↓ ↓H␈↓condition on a list-constructing function, such as the following function, ␈↓αdotem␈↓, returns ␈↓α( )␈↓.
␈↓ ↓H␈↓␈↓↓1.9␈↓ λrBecoming an Expert 47␈↓
␈↓ ↓H␈↓The␈αarguments␈αto␈α␈↓αdotem␈↓␈αare␈α
both␈αlists␈αassumed␈αto␈αcontain␈α
the␈αsame␈αnumber␈αof␈αelements.␈αThe␈α
value
␈↓ ↓H␈↓returned␈αis␈αto␈αbe␈αa␈αlist␈αof␈αdotted␈αpairs;␈αthe␈αelements␈αof␈αthe␈αpairs␈αare␈αthe␈αcorresponding␈αelements␈αof
␈↓ ↓H␈↓the input lists. Thus:
␈↓ ↓H␈↓αdotem[x;y] <= [␈↓ βλnull[x] → ( );
␈↓ ↓H␈↓α␈↓ βλ␈↓
t␈↓α → concat[cons[first[x];first[y]];dotem[rest[x];rest[y]]]]
␈↓ ↓H␈↓The␈α∂first␈α∞thing␈α∂to␈α∂note␈α∞is␈α∂the␈α∞use␈α∂of␈α∂both␈α∞␈↓αconcat␈↓␈α∂and␈α∞␈↓αcons␈↓:␈α∂␈↓αconcat␈↓␈α∂is␈α∞used␈α∂to␈α∞build␈α∂the␈α∂final␈α∞list
␈↓ ↓H␈↓output;␈α␈↓αcons␈↓␈α
is␈αused␈α
to␈αbuild␈αthe␈α
dotted␈αpairs.␈α
Now␈αif␈α
we␈αhad␈αwritten␈α
␈↓αdotem␈↓␈αsuch␈α
that␈αit␈αknew␈α
about
␈↓ ↓H␈↓our␈α∞representation␈α∞of␈α∞lists,␈α∞then␈α∞␈↓↓both␈↓␈α∞functions␈α∞would␈α∞have␈α∞been␈α∞␈↓αcons␈↓.␈α∞The␈α∞definition␈α∂would␈α∞not
␈↓ ↓H␈↓have been as clear.
␈↓ ↓H␈↓Look at a computation as simple as ␈↓αdotem[(A);(B)]␈↓. This will involve
␈↓ ↓H␈↓␈↓ ¬ ␈↓αconcat[cons[A;B];dotem[( );( )]].
␈↓ ↓H␈↓α␈↓Now the evaluation of ␈↓αdotem[( );( )]␈↓ returns our needed ␈↓α( )␈↓, giving
␈↓ ↓H␈↓␈↓ ∧↓␈↓αconcat[cons[A;B];( )] = concat[(A . B);( )] = ((A . B))
␈↓ ↓H␈↓If␈α∞the␈α∂termination␈α∞condition␈α∞of␈α∂␈↓αdotem␈↓␈α∞returned␈α∂anything␈α∞other␈α∞than␈α∂␈↓α( )␈↓␈α∞then␈α∂the␈α∞list-construction
␈↓ ↓H␈↓would "get off on the wrong foot" and would not generate a list.
␈↓ ↓H␈↓As promised on page 46, here is a "direct" definition of ␈↓αreverse␈↓.
␈↓ ↓H␈↓αreverse[x] <=␈↓ βλ[null[x] → ( );
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α → append[reverse[rest[x]];concat[first[x];( )]]]
␈↓ ↓H␈↓This␈α∂reversing␈α∂function␈α∂is␈α∂not␈α∂as␈α∂efficient␈α∂as␈α∂the␈α∂previous␈α∂one.␈α∂ Within␈α∂the␈α∂construction␈α⊂of␈α∂the
␈↓ ↓H␈↓reversed␈α∃list␈α∃the␈α∃␈↓αappend␈↓␈α∃function␈α⊗is␈α∃called␈α∃repeatedly.␈α∃You␈α∃should␈α∃evaluate␈α⊗something␈α∃like
␈↓ ↓H␈↓␈↓αreverse[(A B C D)]␈↓ to see the difficulty.
␈↓ ↓H␈↓It␈α∩␈↓↓is␈↓␈α∩possible␈α∩to␈α∩write␈α∩a␈α∩directly␈α∩recursive␈α∩reversing␈α∩function␈α∩with␈α∩no␈α∩auxiliary␈α∪functions,␈α∩no
␈↓ ↓H␈↓functions␈α
other␈α
than␈α
the␈αprimitives,␈α
and␈α
with␈α
not␈αmuch␈α
clarity.␈α
We␈α
shall␈αpersist␈α
because␈α
it␈α
is␈αa␈α
good
␈↓ ↓H␈↓example␈αof␈αdiscovering␈αthe␈αgeneral␈αcase␈αof␈αthe␈αrecursion␈αby␈αcareful␈αconsideration␈αof␈αexamples.␈αLet
␈↓ ↓H␈↓us call the function ␈↓αrev␈↓.
␈↓ ↓H␈↓We␈α∞consider␈α
the␈α∞general␈α
case␈α∞first,␈α
and␈α∞postpone␈α
the␈α∞termination␈α
conditions␈α∞until␈α∞later.␈α
Consider,
␈↓ ↓H␈↓for␈αexample,␈α␈↓αrev[(A B C D)]␈↓.␈αThis␈αshould␈αevaluate␈αto␈α␈↓α(D C B A)␈↓.␈αHow␈αcan␈αwe␈αconstruct␈αthis␈αlist␈αby
␈↓ ↓H␈↓recursive␈α
calls␈α
on␈α
␈↓αrev␈↓?␈α
Assume␈α∞␈↓αx␈↓␈α
has␈α
value␈α
␈↓α(A B C D)␈↓.␈α
Now␈α∞note␈α
that␈α
␈↓α(D C B A)␈↓␈α
is␈α
the␈α∞value␈α
of
␈↓ ↓H␈↓␈↓αconcat[D;(C B A)]␈↓.␈α∞Then␈α∞␈↓αD␈↓␈α
is␈α∞␈↓αfirst[rev[rest[x]]]␈↓␈α∞(it␈α∞is␈α
also␈α∞␈↓αfirst[rev[x]]␈↓␈α∞but␈α
that␈α∞would␈α∞not␈α∞help␈α
us
␈↓ ↓H␈↓since the recursion must reduce the complexity of the argument).
␈↓ ↓H␈↓␈↓↓48 Symbolic expressions␈↓ 71.9␈↓
␈↓ ↓H␈↓How can we get ␈↓α(C B A)␈↓? Well:
␈↓ ↓H␈↓α␈↓ ∧λ(C B A)␈↓ ¬_= rev[(A B C)]
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_= rev[concat[A;(B C)]] ␈↓(we are going after ␈↓αrest[x]␈↓ again)␈↓α
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_ ␈↓but first we can get ␈↓αA␈↓ from ␈↓αx.
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_= rev[concat[first[x];(B C)]]
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_= rev[concat[first[x];rev[(C B)]]]
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_= rev[concat[first[x];rev[rest[(D C B)]]]]
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_= rev[concat[first[x];rev[rest[rev[rest[x]]]]]]
␈↓ ↓H␈↓α␈↓Finally␈↓α
␈↓ ↓H␈↓α␈↓ αwrev[x] = concat[first[rev[rest[x]]];rev[concat[first[x];rev[rest[rev[rest[x]]]]]]]
␈↓ ↓H␈↓Now,␈αthe␈αtermination␈αconditions␈αare␈α
simple.␈αFirst␈α␈↓αrev[( )]␈↓␈αgives␈α␈↓α( )␈↓.␈α
But␈αnotice␈αthat␈αthe␈αgeneral␈α
case
␈↓ ↓H␈↓which␈α
we␈α
just␈α
constructed␈α
has␈α
␈↓↓two␈↓␈α
␈↓αconcat␈↓s.␈α
That␈α∞means␈α
the␈α
shortest␈α
list␈α
which␈α
it␈α
can␈α
make␈α∞is␈α
of
␈↓ ↓H␈↓length␈α∞two.␈α
So␈α∞lists␈α
of␈α∞length␈α
one␈α∞are␈α
also␈α∞handled␈α
separately:␈α∞the␈α
reverse␈α∞of␈α
such␈α∞a␈α
list␈α∞is␈α
itself.
␈↓ ↓H␈↓Thus the complete definition should be:
␈↓ ↓H␈↓αrev[x] <= [␈↓ αXnull[x] → ( );
␈↓ ↓H␈↓α␈↓ αXnull[rest[x]] → x;
␈↓ ↓H␈↓α␈↓ αX␈↓
t␈↓α → concat[first[rev[rest[x]]];rev[concat[first[x];rev[rest[rev[rest[x]]]]]]] ]
␈↓ ↓H␈↓We␈αhave␈αonly␈αhinted␈αat␈αthe␈αissue␈αof␈αefficiency␈αin␈αcomputation.␈αThe␈αquestion␈αof␈αefficiency␈αinvolves
␈↓ ↓H␈↓deeper␈α⊃questions␈α∩of␈α⊃the␈α∩evaluation␈α⊃mechanisms.␈α∩We␈α⊃will␈α⊃return␈α∩to␈α⊃these␈α∩issues␈α⊃after␈α∩we␈α⊃have
␈↓ ↓H␈↓discussed the LISP evaluation scheme more completely.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I Use the following definition:
␈↓ ↓H␈↓α␈↓ αXmatch[k;m] <=␈↓ ∧([null[k] → NO;
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧( null[m] → NO;
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧( eq[first[k];first[m]] → first[k];
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧( ␈↓
t␈↓α → match[rest[k];rest[m]]]
␈↓ ↓H␈↓and evaluate:
␈↓ ↓H␈↓␈↓↓1.␈↓α match[(X);(X)] ␈↓↓2.␈↓α match[(A B E);(J O E)] ␈↓↓3.␈↓α match[(F O O); (B A Z)]
␈↓ ↓H␈↓␈↓↓1.9␈↓ λrBecoming an Expert 49␈↓
␈↓ ↓H␈↓II Now write your own functions:
␈↓ ↓H␈↓␈↓↓1.␈↓α␈α
among[x;y]␈α
<=␈α
...␈α
:␈α
among␈↓␈α
is␈αto␈α
be␈α
a␈α
predicate;␈α
␈↓αx␈↓␈α
is␈α
an␈α
atom;␈α␈↓αy␈↓␈α
is␈α
a␈α
list␈α
of␈α
atoms.␈α
␈↓αamong␈↓␈α
is␈αto␈α
return
␈↓ ↓H␈↓␈↓ βX␈↓
f␈↓ if ␈↓αx␈↓ is not found as an element of ␈↓αy␈↓; otherwise, ␈↓αamong␈↓ is to return ␈↓
t␈↓.
␈↓ ↓H␈↓␈↓ αXe.g. ␈↓αamong[A;(A B C)] = among[A;(C D E A)] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ αX among[A1;(A2 B2)] = ␈↓
f␈↓α.
␈↓ ↓H␈↓␈↓↓2.␈↓α␈α⊂anywhere[x;y]␈α⊂<=␈α∂...␈α⊂:␈α⊂anywhere␈↓␈α⊂is␈α∂a␈α⊂predicate;␈α⊂␈↓αx␈↓␈α⊂is␈α∂an␈α⊂atom;␈α⊂␈↓αy␈↓␈α⊂is␈α∂an␈α⊂arbitrary␈α⊂S-expr␈α⊂or␈α∂list.
␈↓ ↓H␈↓␈↓ ∧_␈↓αanywhere␈↓ is to return ␈↓
t␈↓ just in the case that ␈↓αx␈↓ appears somewhere in ␈↓αy␈↓.
␈↓ ↓H␈↓␈↓ αXe.g. ␈↓αanywhere[A;(A B C)] = anywhere[A;((A . B) . C)] = ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ αX anywhere[A;(B C D)] = ␈↓
f␈↓α.
␈↓ ↓H␈↓␈↓↓3.␈↓α␈α∪collectpair[z;x;y]␈α∀<=␈α∪...␈α∀:␈α∪x␈↓␈α∀and␈α∪␈↓αy␈↓␈α∀are␈α∪atoms;␈α∪␈↓αz␈↓␈α∀is␈α∪an␈α∀S-expression␈α∪or␈α∀list,␈α∪some␈α∀of␈α∪whose
␈↓ ↓H␈↓␈↓ ∧Hsubexpressions,␈α∞may␈α∂begin␈α∞␈↓α(x␈α∂...)␈↓␈α∞or␈α∞␈↓α(y␈α∂...)␈↓.␈α∞ ␈↓αcollectpair␈↓␈α∂is␈α∞to␈α∂return␈α∞a
␈↓ ↓H␈↓␈↓ ∧Hdotted␈αpair␈αwhose␈α␈↓αcar␈↓-part␈αis␈αa␈αlist␈αof␈αall␈αthe␈αoccurrences␈αof␈α␈↓α(x...)␈↓␈αand
␈↓ ↓H␈↓␈↓ ∧Hwhose ␈↓αcdr␈↓-part is a list of all occurrences of ␈↓α(y ...)␈↓.
␈↓ ↓H␈↓␈↓ αXe.g. ␈↓αcollectpair[((A 1) ((B . 2) (C A 4)));A;B] = (((A 1) (A 4)) . ((B . 2)))
␈↓ ↓H␈↓␈↓↓4.␈↓α␈α⊃pred[x]␈α⊃<=␈α⊃...␈α⊃:␈α∩x␈↓␈α⊃is␈α⊃a␈α⊃positive␈α⊃integer.␈α⊃␈↓αpred␈↓␈α∩is␈α⊃a␈α⊃function,␈α⊃returning␈α⊃the␈α⊃predecessor␈α∩of␈α⊃its
␈↓ ↓H␈↓␈↓ βHargument. The only arithmetic function you may use is ␈↓αadd1␈↓.
␈↓ ↓H␈↓␈↓ αXe.g. ␈↓αpred[3] = 2; pred[0] ␈↓is undefined␈↓α;
␈↓ ↓H␈↓α␈↓ αX pred[add1[x]] = x ␈↓ for ␈↓αx ␈↓≥␈↓α 0.␈↓
␈↓ ↓H␈↓␈↓↓5.␈↓α␈αsignum[x]␈α<=␈α...␈α:␈αx␈↓␈αis␈αan␈αinteger.␈α␈↓αsignum␈↓␈αreturns␈α␈↓αNEGATIVE␈↓,␈α␈↓αZERO␈↓,␈αor␈α
␈↓αPOSITIVE␈↓␈αdepending
␈↓ ↓H␈↓␈↓ βhon␈α∞the␈α
sign␈α∞of␈α
␈↓αx␈↓.␈α∞You␈α∞may␈α
use␈α∞␈↓αadd1␈↓␈α
and␈α∞␈↓αsub1␈↓␈α
but␈α∞no␈α∞comparision␈α
function
␈↓ ↓H␈↓␈↓ βhother than ␈↓αeq␈↓.
␈↓ ↓H␈↓␈↓↓6.␈↓α␈α∞maxdepth[l]␈α∞<=␈α∞...␈α∞:␈α∞l␈↓␈α∞is␈α∞a␈α∞list.␈α∞This␈α∞function␈α∞is␈α∞to␈α∞find␈α∞the␈α∞maximum␈α∞depth␈α∞of␈α∞nesting␈α∞of␈α
any
␈↓ ↓H␈↓␈↓ βxelement␈α∀in␈α∀␈↓αl␈↓.␈α∪Assume␈α∀that␈α∀␈↓αl␈↓␈α∀is␈α∪a␈α∀strict␈α∀list␈α∪(see␈α∀page 34);␈α∀that␈α∀is,␈α∪any
␈↓ ↓H␈↓␈↓ βxsub-element␈α→is␈α→either␈α→atomic␈α→or␈α_is␈α→itself␈α→a␈α→strict␈α→list.␈α→ For␈α_example
␈↓ ↓H␈↓␈↓ βx␈↓αmaxdepth[( )] = 0; maxdepth[(((B) C) A)] = 3.␈↓
␈↓ ↓H␈↓␈↓↓50 Applications␈↓ C2.␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓↓CHAPTER 2
␈↓ ↓H␈↓↓␈↓ ¬→APPLICATIONS OF LISP␈↓
␈↓ ↓H␈↓␈↓ ∧λ"...All␈αthe␈αtime␈αI␈α
design␈αprograms␈αfor␈αnonexisting␈α
machines␈αand␈αadd:␈α`if␈α
we
␈↓ ↓H␈↓␈↓ ∧λnow␈αhad␈αa␈αmachine␈αcomprising␈αthe␈αprimitives␈αhere␈αassumed,␈αthen␈αthe␈αjob
␈↓ ↓H␈↓␈↓ ∧λis done.'
␈↓ ↓H␈↓␈↓ ∧λ...␈αIn␈α
actual␈αpractice,␈α
of␈αcourse,␈αthis␈α
ideal␈αmachine␈α
will␈αturn␈α
out␈αnot␈αto␈α
exist,
␈↓ ↓H␈↓␈↓ ∧λso␈α∞our␈α∞next␈α∞task␈α∞--structurally␈α∞similar␈α∞to␈α∞the␈α∞original␈α∞one--␈α∞is␈α∞to␈α∞program
␈↓ ↓H␈↓␈↓ ∧λthe␈α∂simulation␈α∂of␈α∂the␈α∂"upper"␈α∞machine....␈α∂But␈α∂this␈α∂bunch␈α∂of␈α∂programs␈α∞is
␈↓ ↓H␈↓␈↓ ∧λwritten␈αfor␈αa␈αmachine␈αthat␈αin␈αall␈αprobability␈αwill␈αnot␈αexist,␈αso␈αour␈αnext␈αjob
␈↓ ↓H␈↓␈↓ ∧λwill␈αbe␈αto␈αsimulate␈αit␈αin␈αterms␈αof␈αprograms␈αfor␈αa␈αnext␈αlower␈αlevel␈αmachine,
␈↓ ↓H␈↓␈↓ ∧λetc.,␈α∃until␈α∃finally␈α⊗we␈α∃have␈α∃a␈α∃program␈α⊗that␈α∃can␈α∃be␈α∃executed␈α⊗by␈α∃our
␈↓ ↓H␈↓␈↓ ∧λhardware...."
␈↓ ↓H␈↓␈↓ $E. W. Dijkstra, [Dij 72]
␈↓ ↓H␈↓␈↓ ¬`␈↓↓2.1 Introduction␈↓
␈↓ ↓H␈↓There␈αare␈αseveral␈α
ways␈αof␈αinterpreting␈αthis␈α
remark␈αof␈αDijkstra.␈α Anyone␈α
who␈αhas␈αprogrammed␈αat␈α
a
␈↓ ↓H␈↓level␈αhigher␈αthan␈αmachine␈αlanguage␈αhas␈αexperienced␈αthe␈αphenomenon.␈αThe␈αact␈αof␈αprogramming␈αin
␈↓ ↓H␈↓a␈αhigh-level␈αlanguage␈αis␈αthat␈αof␈αwriting␈αalgorithms␈αfor␈αa␈αnonexistent␈αhigh-level␈αmachine.␈αTypically
␈↓ ↓H␈↓however,␈αthe␈αchanges␈αof␈α
representation␈αfrom␈αmachine␈αto␈α
machine␈αare␈αall␈αdone␈α
automatically:␈αfrom
␈↓ ↓H␈↓high-level, to assembly language, and finally to hardware instructions.
␈↓ ↓H␈↓A␈α∩related␈α∪view␈α∩of␈α∩Dijkstra's␈α∪remark␈α∩involves␈α∪our␈α∩discussions␈α∩of␈α∪abstract␈α∩data␈α∪structures␈α∩and
␈↓ ↓H␈↓algorithms.␈α We␈αexpress␈αour␈α
algorithms␈αand␈αdata␈αstructures␈α
in␈αterms␈αof␈αabstractions␈αindependent␈α
of
␈↓ ↓H␈↓how␈αthey␈αmay␈αbe␈αrepresented␈α
in␈αa␈αmachine;␈αindeed␈αwe␈α
can␈αuse␈αthe␈αideas␈αof␈α
abstraction␈α␈↓↓regardless␈↓
␈↓ ↓H␈↓of␈α
whether␈α
the␈α
formalism␈α
will␈α
find␈α
a␈α∞representation␈α
on␈α
a␈α
machine.␈α
This␈α
use␈α
of␈α
abstraction␈α∞is␈α
the
␈↓ ↓H␈↓true␈αsense␈α
of␈αthe␈αprogramming␈α
style␈αcalled␈α"structured␈α
programming".␈α We␈αwill␈α
see␈αin␈α
this␈αchapter
␈↓ ↓H␈↓how␈α∃this␈α∃programming␈α∃style␈α∃is␈α∃a␈α∃natural␈α∃result␈α∃of␈α∃writing␈α∃representation-independent␈α∃LISP
␈↓ ↓H␈↓programs.
␈↓ ↓H␈↓As␈α⊂we␈α⊃have␈α⊂previously␈α⊃remarked,␈α⊂we␈α⊂will␈α⊃see␈α⊂a␈α⊃close␈α⊂relationship␈α⊂between␈α⊃the␈α⊂structure␈α⊃of␈α⊂an
␈↓ ↓H␈↓algorithm␈αand␈α
the␈αstructure␈αof␈α
the␈αdata.␈α We␈α
have␈αseen␈α
this␈αalready␈αon␈α
a␈αsmall␈αscale:␈α
list-algorithms
␈↓ ↓H␈↓tend␈α
to␈α
recur␈α
"linearly"␈αon␈α
␈↓αrest␈↓␈α
to␈α
␈↓α( )␈↓;␈αS-expr␈α
algorithms␈α
tend␈α
to␈αrecur␈α
"left-and-right"␈α
on␈α
␈↓αcar␈↓␈αand␈α
␈↓αcdr␈↓
␈↓ ↓H␈↓to␈αan␈αatom.␈α Indeed,␈αthe␈αinstances␈αof␈αcontrol␈αstructures␈αappearing␈αin␈αan␈αalgorithm␈αtypically␈αparallel
␈↓ ↓H␈↓the style of inductive definition of the data structure which the algorithm is examining.
␈↓ ↓H␈↓␈↓↓2.1␈↓ ↑Introduction 51␈↓
␈↓ ↓H␈↓If a structure is defined as:
␈↓ ↓H␈↓␈↓ ¬Z␈↓
D␈↓ ::= ␈↓
D␈↓β1␈↓ | ␈↓
D␈↓β2␈↓ | ␈↓
D␈↓β3␈↓
␈↓ ↓H␈↓␈↓ ∧oe.g. <seq elem> ::= <indiv> | <seq>
␈↓ ↓H␈↓then␈α∂we␈α∂can␈α∂expect␈α∂to␈α∂find␈α∂a␈α∂conditional␈α∂expression␈α∂whose␈α∂predicate␈α∂positions␈α∂are␈α∂filled␈α∂by␈α∞the
␈↓ ↓H␈↓recognizers for the ␈↓
D␈↓βi␈↓'s.
␈↓ ↓H␈↓If the structure is defined as:
␈↓ ↓H␈↓␈↓ ¬o␈↓
D␈↓ ::= ␈↓
D␈↓β1␈↓ ... ␈↓
D␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ∧Be.g. <seq> ::= ␈↓↓(␈↓<seq elem>␈↓↓,␈↓ ..., <seq elem>␈↓↓)␈↓
␈↓ ↓H␈↓that␈α⊃is,␈α⊃a␈α⊃homogeneous␈α⊃sequence␈α⊂of␈α⊃elements,␈α⊃then␈α⊃we␈α⊃will␈α⊂have␈α⊃a␈α⊃"linear"␈α⊃recursion␈α⊃like␈α⊂that
␈↓ ↓H␈↓experienced in list-algorithms␈↓π 42␈↓.
␈↓ ↓H␈↓Finally if the structure is defined with a fixed number of components as:
␈↓ ↓H␈↓␈↓ ¬K␈↓
D␈↓ ::= ␈↓
D␈↓β1␈↓ ␈↓
D␈↓β2␈↓ ␈↓
D␈↓β3␈↓... ␈↓
D␈↓βn␈↓
␈↓ ↓H␈↓␈↓ ∧Ze.g. <sexpr> ::= ␈↓α(␈↓<sexpr> . <sexpr>␈↓α)␈↓
␈↓ ↓H␈↓then we can expect occurrences of selector functions to extract the components from the structure␈↓π 43␈↓.
␈↓ ↓H␈↓Thus␈αa␈αdata-structure␈αalgorithm␈αtends␈αto␈α"pass␈αoff"␈αits␈αwork␈αto␈αsubfunctions␈αwhich␈αwill␈αoperate␈αon
␈↓ ↓H␈↓the␈αcomponents␈α
of␈αthe␈αdata␈α
structure.␈αThus␈αif␈α
a␈αstructure␈αof␈α
type␈α␈↓
D␈↓␈αis␈α
made␈αup␈αof␈α
components␈αof
␈↓ ↓H␈↓types␈α
␈↓
D␈↓β1␈↓,␈α
␈↓
D␈↓β2␈↓,␈α␈↓
D␈↓β3␈↓,␈α
and␈α
␈↓
D␈↓β4␈↓,␈αthen␈α
the␈α
structure␈α
of␈αan␈α
algorithm␈α
␈↓αf␈↓␈αoperating␈α
on␈α
␈↓
D␈↓␈α
typically␈αinvolves
␈↓ ↓H␈↓calls␈α
on␈α
subfunctions␈α␈↓αf␈↓β1␈↓␈α
through␈α
␈↓αf␈↓β4␈↓␈αto␈α
handle␈α
the␈α
subcomputations.␈αEach␈α
␈↓αf␈↓βi␈↓␈α
will␈αin␈α
turn␈α
break␈αup␈α
its
␈↓ ↓H␈↓␈↓
D␈↓βi␈↓.
␈↓ ↓H␈↓Thus the type-structure of the call on ␈↓αf␈↓ would be:
␈↓ ↓H␈↓␈↓ ∧]␈↓αf[␈↓
D␈↓α] = g[f␈↓β1␈↓α[␈↓
D␈↓β1␈↓α];f␈↓β2␈↓α[␈↓
D␈↓β2␈↓α];f␈↓β3␈↓α[␈↓
D␈↓β3␈↓α];f␈↓β4␈↓α[␈↓
D␈↓β4␈↓α]]
␈↓ ↓H␈↓This␈α⊗is␈α⊗the␈α⊗essence␈α∃of␈α⊗level-wise␈α⊗programming:␈α⊗we␈α∃write␈α⊗␈↓αf,␈α⊗f␈↓β1␈↓α, ... , f␈↓β4␈↓␈α⊗independently␈α⊗of␈α∃the
␈↓ ↓H␈↓representation␈αof␈αtheir␈αdata␈αstructures.␈α ␈↓αf␈↓␈αwill␈αrun␈αprovided␈αthat␈αthe␈α␈↓αf␈↓βi␈↓'s␈αare␈αavailable.␈αAs␈αwe␈αwrite
␈↓ ↓H␈↓the␈α⊃␈↓αf␈↓βi␈↓'s␈α⊃we␈α∩will␈α⊃probably␈α⊃invoke␈α∩computations␈α⊃on␈α⊃components␈α∩of␈α⊃the␈α⊃corresponding␈α∩␈↓
D␈↓βi␈↓.␈α⊃Those
␈↓ ↓H␈↓computations␈α∩are␈α∩in␈α∩turn␈α∩executed␈α∩by␈α∩subfunctions␈α∩which␈α∩we␈α∩have␈α∩to␈α∩write.␈α∩This␈α∪process␈α∩of
␈↓ ↓H␈↓elaboration␈α⊃terminates␈α⊂when␈α⊃all␈α⊂subfunctions␈α⊃are␈α⊂written␈α⊃and␈α⊂all␈α⊃data␈α⊂structures␈α⊃have␈α⊂received
␈↓ ↓H␈↓concrete␈α∞representations.␈α∞In␈α
LISP␈α∞this␈α∞means␈α∞the␈α
lowest␈α∞level␈α∞functions␈α
are␈α∞expressed␈α∞in␈α∞terms␈α
of
␈↓ ↓H␈↓LISP␈α
primitives␈α
and␈α
the␈α
data␈α
structures␈α
are␈α
represented␈α
in␈α
terms␈α
of␈α
S-exprs.␈α
Thus␈α
at␈α
the␈αhighest
␈↓ ↓H␈↓level␈αwe␈αtend␈αto␈αthink␈αof␈αa␈αdata␈αstructure␈αas␈αa␈αclass␈αof␈αbehaviors;␈αwe␈αdon't␈αcare␈αabout␈αthe␈αinternal
␈↓ ↓H␈↓mechanisms␈α∀which␈α∀implement␈α∪that␈α∀behavior.␈α∀ At␈α∪the␈α∀lowest␈α∀level,␈α∀machine-language␈α∪routines
␈↓ ↓H␈↓simulate ␈↓↓one␈↓ of many possible representations.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 42␈↓␈αIndeed␈αthere␈αare␈αother␈αforms␈αof␈αcontrol␈αlike␈αiteration␈αor␈α␈↓αlit␈↓␈α(page 182)␈αwhich␈αare␈αrelated␈αto␈α
such
␈↓ ↓H␈↓data structures.
␈↓ ↓H␈↓␈↓π 43␈↓␈αYou␈αmay␈αhave␈αnoticed␈αthat␈αwe␈α
are␈αtherefore␈αdealing␈αwith␈αessentially␈α"context-free"␈αabstract␈α
data
␈↓ ↓H␈↓structures; i.e., those generated by context-free grammars.[Hop 69].
␈↓ ↓H␈↓␈↓↓52 Applications␈↓ 72.1␈↓
␈↓ ↓H␈↓This␈α⊃process␈α⊃of␈α⊃elaboration␈α⊃of␈α⊃abstract␈α⊃algorithm␈α⊃and␈α⊃abstract␈α⊃data␈α⊃structure␈α⊃may␈α∩modify␈α⊃the
␈↓ ↓H␈↓top-level␈α∪definition␈α∩of␈α∪␈↓αf␈↓.␈α∩Implementation␈α∪considerations␈α∩may␈α∪effect␈α∩some␈α∪earlier␈α∪decisions␈α∩and
␈↓ ↓H␈↓require␈α
replanning␈α
of␈α
an␈α
earlier␈α
strategy.␈α
At␈α
that␈α
time␈α
the␈α
complete␈α
plan␈α
should␈α
be␈αre-examined;
␈↓ ↓H␈↓local␈αmodifications␈αmay␈αhave␈αglobal␈αrepercussions.␈α A␈αprogramming␈αstyle␈αis␈αnot␈αa␈αpanacea;␈αit␈αis␈αno
␈↓ ↓H␈↓substitute for clear thinking. It only helps control the complexity of the programming process.
␈↓ ↓H␈↓␈↓ ∧\␈↓↓2.2 Examples of LISP Applications␈↓
␈↓ ↓H␈↓The␈α⊂next␈α⊂few␈α⊂sections␈α⊂will␈α⊂examine␈α⊂some␈α⊂non-trivial␈α⊂problems␈α⊂involving␈α⊂computations␈α⊂on␈α∂data
␈↓ ↓H␈↓structures.␈α We␈αwill␈αdescribe␈αthe␈αproblem␈αintuitively,␈αpick␈αan␈αinitial␈αrepresentation␈αfor␈αthe␈αproblem,
␈↓ ↓H␈↓write␈αthe␈αLISP␈αalgorithm,␈αand␈αin␈αsome␈αcases␈α"tune"␈αthe␈αalgorithm␈αby␈αpicking␈α"more␈αefficient"␈αdata
␈↓ ↓H␈↓representations.
␈↓ ↓H␈↓The examples share other important characteristics:
␈↓ ↓H␈↓␈↓↓1.␈↓ We examine the problem domain and attempt to represent its elements as data structures.
␈↓ ↓H␈↓␈↓↓2.␈↓␈α∩We␈α⊃reflect␈α∩on␈α∩our␈α⊃(intuitive)␈α∩algorithm␈α⊃and␈α∩try␈α∩to␈α⊃express␈α∩it␈α⊃as␈α∩a␈α∩LISP-like␈α⊃data-structure
␈↓ ↓H␈↓manipulating function.
␈↓ ↓H␈↓␈↓↓3.␈↓␈αWhile␈αperforming␈α␈↓↓1␈↓␈αand␈α␈↓↓2␈↓,␈αwe␈αmight␈αhave␈αto␈αmodify␈αsome␈αof␈αour␈αdecisions.␈αSomething␈αassumed
␈↓ ↓H␈↓to␈α∩be␈α∩structure␈α∩might␈α∪better␈α∩be␈α∩represented␈α∩as␈α∩algorithm,␈α∪or␈α∩some␈α∩algorithm␈α∩might␈α∪be␈α∩better
␈↓ ↓H␈↓repesented as a data structure.
␈↓ ↓H␈↓␈↓↓4.␈↓ When the decisions are made, we evaluate the LISP function on a representation of a problem.
␈↓ ↓H␈↓␈↓↓5.␈↓ We reinterpret the data-structure output as an answer to our problem.
␈↓ ↓H␈↓Pictorially in terms of LISP:
␈↓ ↓H␈↓intuitive algorithm => LISP function␈↓ ¬h|
␈↓ ↓H␈↓␈↓ ¬h| evaluation
␈↓ ↓H␈↓␈↓ ¬h|==============> interpret S-expr output as answer
␈↓ ↓H␈↓␈↓ ¬h|
␈↓ ↓H␈↓problem domain => S-expressions␈↓ ¬h|
␈↓ ↓H␈↓Whenever␈αwe␈α
write␈αcomputer␈αprograms,␈α
whatever␈αlanguage␈αwe␈α
use,␈αwe␈αalways␈α
go␈αthrough␈αa␈α
similar
␈↓ ↓H␈↓representation␈αproblem.␈αThe␈αprocess␈αis␈αmore␈αapparent␈αin␈αa␈αhigher-level␈αlanguage␈αlike␈αFORTRAN
␈↓ ↓H␈↓or␈α⊃ALGOL,␈α⊂and␈α⊃is␈α⊂most␈α⊃noticeable␈α⊂in␈α⊃a␈α⊂language␈α⊃like␈α⊂LISP␈α⊃which␈α⊂primarily␈α⊃deals␈α⊃with␈α⊂data
␈↓ ↓H␈↓structures.
␈↓ ↓H␈↓␈↓↓2.2␈↓ πXExamples of LISP Applications 53␈↓
␈↓ ↓H␈↓When␈α∞we␈α
deal␈α∞with␈α
numerical␈α∞algorithms,␈α
the␈α∞representation␈α
problem␈α∞has␈α
usually␈α∞been␈α∞settled␈α
in
␈↓ ↓H␈↓the␈α⊃transformation␈α∩from␈α⊃real-world␈α∩situation␈α⊃to␈α∩a␈α⊃numerical␈α∩problem.␈α⊃One␈α∩has␈α⊃to␈α∩think␈α⊃more
␈↓ ↓H␈↓explicitly␈α∪about␈α∩representation␈α∪when␈α∪we␈α∩deal␈α∪with␈α∩structures␈α∪like␈α∪arrays␈α∩or␈α∪matrices.␈α∪We␈α∩are
␈↓ ↓H␈↓encoding␈αour␈α
information␈αin␈α
the␈αarray.␈αBut␈α
the␈αpreceding␈α
diagram␈αoccurs␈α
within␈αthe␈αmachine,␈α
even
␈↓ ↓H␈↓for strictly non-structured numerical calculation.
␈↓ ↓H␈↓numerical algorithm => machine instructions␈↓ ε8|
␈↓ ↓H␈↓␈↓ ε8| execution
␈↓ ↓H␈↓␈↓ ε8|==========> interpret binary number as answer
␈↓ ↓H␈↓␈↓ ε8|
␈↓ ↓H␈↓numbers => binary representation␈↓ ε8|
␈↓ ↓H␈↓The␈α∂encodings␈α⊂are␈α∂done␈α⊂by␈α∂the␈α⊂input␈α∂routines.␈α∂The␈α⊂result␈α∂of␈α⊂the␈α∂execution␈α⊂is␈α∂presented␈α⊂to␈α∂the
␈↓ ↓H␈↓external world by the output routines.
␈↓ ↓H␈↓However,␈αwhen␈αwe␈αcome␈αto␈αdata-structure␈αcomputations,␈αthe␈αrepresentation␈αproblem␈αreally␈αbecomes
␈↓ ↓H␈↓apparent.␈α We␈α
have␈αto␈α
think␈αmore␈α
about␈αwhat␈α
we␈αare␈α
doing␈αsince␈α
we␈αlack␈α
certain␈αpreconceptions␈α
or
␈↓ ↓H␈↓intuitions␈α
about␈α
such␈α∞computations.␈α
More␈α
importantly,␈α
we␈α∞are␈α
trying␈α
to␈α
represent␈α∞actual␈α
problems
␈↓ ↓H␈↓␈↓↓directly␈↓␈α↔as␈α↔machine␈α⊗problems.␈α↔We␈α↔do␈α↔not␈α⊗attempt␈α↔to␈α↔first␈α⊗analyze␈α↔them␈α↔into␈α↔a␈α⊗complex
␈↓ ↓H␈↓mathematical␈α↔theory,␈α↔but␈α_try␈α↔to␈α↔express␈α↔our␈α_intuitive␈α↔theory␈α↔directly␈α↔as␈α_manipulations␈α↔of
␈↓ ↓H␈↓data-structures.␈α⊃ This␈α⊃is␈α⊃a␈α⊃different␈α⊃kind␈α⊃of␈α⊃thinking,␈α⊃due␈α⊃wholly␈α⊃to␈α⊃the␈α⊃advent␈α⊃of␈α⊃computers.
␈↓ ↓H␈↓Indeed␈α
the␈α
field␈α
of␈α
computation␈α
has␈α
expanded␈α
so␈α
much␈α
as␈α
to␈α
make␈α
the␈α
term␈α
"computer"␈αobsolete.
␈↓ ↓H␈↓"Structure processor" is more indicative of the proper level at which we should view "computers".
␈↓ ↓H␈↓We␈α∪have␈α∪already␈α∩seen␈α∪a␈α∪simple␈α∪example␈α∩of␈α∪the␈α∪representation␈α∩problem␈α∪in␈α∪the␈α∪discussion␈α∩of
␈↓ ↓H␈↓list-notation beginning in Section 1.6.
␈↓ ↓H␈↓sequence algorithm => LISP function␈↓ ¬h|
␈↓ ↓H␈↓␈↓ ¬h| evaluation
␈↓ ↓H␈↓␈↓ ¬h|============> re-interpret S-expr result as answer.
␈↓ ↓H␈↓␈↓ ¬h|
␈↓ ↓H␈↓sequence expression => S-expression␈↓ ¬h|
␈↓ ↓H␈↓The following sections deal with representation of complex data structure problems in LISP.
␈↓ ↓H␈↓␈↓ ¬M␈↓↓2.3 Differentiation␈↓
␈↓ ↓H␈↓This␈α∀example␈α∀will␈α∀describe␈α∀a␈α∀rudimentary␈α∀differentiation␈α∀routine␈α∀for␈α∀polynomials␈α∀in␈α∀several
␈↓ ↓H␈↓variables.␈α
We␈α
will␈α
develop␈α
this␈αalgorithm␈α
through␈α
several␈α
stages.␈α
We␈αwill␈α
begin␈α
by␈α
doing␈α
a␈αvery
␈↓ ↓H␈↓direct,␈αbut␈αrepresentation-dependent,␈αimplementation.␈α We␈αwill␈αencode␈αpolynomials␈αas␈α
special␈αLISP
␈↓ ↓H␈↓␈↓↓54 Applications␈↓ 52.3␈↓
␈↓ ↓H␈↓lists␈α⊗and␈α⊗will␈α⊗express␈α⊗the␈α⊗differentiation␈α∃algorithm␈α⊗as␈α⊗a␈α⊗LISP␈α⊗program␈α⊗operating␈α⊗on␈α∃that
␈↓ ↓H␈↓representation.␈α When␈αthis␈αprogram␈αis␈αcompletely␈αspecified␈αwe␈αwill␈αthen␈αscrutinize␈αit,␈αattempting␈αto
␈↓ ↓H␈↓see␈αjust␈αhow␈αmuch␈αof␈αthe␈αprogram␈αand␈αdata␈αstructure␈αis␈αrepresentation␈αand␈αhow␈αmuch␈αis␈αessential
␈↓ ↓H␈↓to the algorithm.
␈↓ ↓H␈↓You␈α∩should␈α∩recognize␈α∩two␈α∩facts␈α∩about␈α∩the␈α∩differentiation␈α∩algorithm␈α∩for␈α∩polynomials:␈α∩first,␈α⊃the
␈↓ ↓H␈↓algorithm␈αoperates␈αon␈αforms␈α(or␈αexpressions)␈αas␈αarguments␈αand␈αreturns␈αforms␈αas␈αvalues.␈αPreviously
␈↓ ↓H␈↓discussed␈α~algorithms␈α→have␈α~operated␈α→on␈α~simple␈α→values␈α~and␈α→produced␈α~simple␈α~values.␈α→The
␈↓ ↓H␈↓differentiation␈α
algorithm␈αtakes␈α
expressions␈αas␈α
arguments␈αand␈α
produces␈αa␈α
new␈αexpression␈α
as␈αvalue.
␈↓ ↓H␈↓Second,␈α⊂you␈α⊂should␈α∂realize␈α⊂that␈α⊂the␈α∂algorithm␈α⊂for␈α⊂differentiation␈α∂is␈α⊂recursive!␈α⊂ The␈α⊂question␈α∂of
␈↓ ↓H␈↓differentiating␈αa␈α
sum␈αis␈αreduced␈α
to␈αthe␈α
ability␈αto␈αdifferentiate␈α
each␈αsummand.␈α Similar␈α
relationships
␈↓ ↓H␈↓hold␈α_for␈α_products,␈α_differences,␈α_and␈α→powers.␈α_ There␈α_must␈α_be␈α_some␈α→termination␈α_conditions.
␈↓ ↓H␈↓Differentiation␈αof␈αa␈αvariable,␈αsay␈α␈↓αx␈↓,␈αwith␈αrespect␈αto␈α␈↓αx␈↓␈αis␈αdefined␈αto␈αbe␈α1;␈αdifferentiating␈αa␈αconstant,
␈↓ ↓H␈↓or␈αa␈αvariable␈αnot␈αequal␈αto␈α␈↓αx␈↓␈αwith␈αrespect␈αto␈α␈↓αx␈↓␈αgives␈αa␈αresult␈αof␈αzero.␈α This␈αbegins␈αto␈αsound␈αlike␈αthe
␈↓ ↓H␈↓␈↓ IND␈↓-definitions␈αof␈αsets␈α(in␈αthis␈αcase␈αthe␈αset␈αof␈αpolynomials)␈αand␈αthe␈αassociated␈α␈↓ REC␈↓-definitions␈αof
␈↓ ↓H␈↓algorithms␈α(in␈αthis␈αcase␈αdifferentiation␈αof␈αpolynomials).␈α If␈αthis␈α␈↓↓is␈↓␈αthe␈αmold␈αinto␈αwhich␈αour␈αcurrent
␈↓ ↓H␈↓problem␈α∩fits,␈α∩then␈α∪we␈α∩must␈α∩give␈α∪an␈α∩inductive␈α∩definition␈α∩of␈α∪our␈α∩set␈α∩of␈α∪polynomials.␈α∩ Though
␈↓ ↓H␈↓polynomials␈α∀can␈α∃be␈α∀arbitrarily␈α∃complex,␈α∀involving␈α∀the␈α∃operations␈α∀of␈α∃addition,␈α∀multiplication,
␈↓ ↓H␈↓negation,␈α⊂and␈α⊃exponentiation,␈α⊂their␈α⊃general␈α⊂format␈α⊃is␈α⊂very␈α⊂simple␈α⊃if␈α⊂they␈α⊃are␈α⊂described␈α⊃in␈α⊂our
␈↓ ↓H␈↓LISP-like␈α
notation␈α
where␈α
the␈α
operation␈α
precedes␈αits␈α
operands.␈α
We␈α
assume␈α
that␈α
binary␈α
plus,␈αtimes,
␈↓ ↓H␈↓and␈α∞exponentiation␈α
are␈α∞symbolized␈α
by␈α∞+,␈α∞*,␈α
and␈α∞↑;␈α
we␈α∞will␈α∞write␈α
␈↓α+[x;2]␈↓␈α∞instead␈α
of␈α∞the␈α∞usual␈α
infix
␈↓ ↓H␈↓notation ␈↓αx+2␈↓. The general term for this LISP-like notation is ␈↓↓prefix notation␈↓.
␈↓ ↓H␈↓Here are some examples of infix and prefix representations:
␈↓ ↓H␈↓␈↓ ¬_␈↓↓infix␈↓ πλprefix
␈↓ ↓H␈↓α␈↓ ¬_x*z+2y␈↓ πλ+[*[x;z]; *[2;y]]
␈↓ ↓H␈↓α␈↓ ¬_x*y*z␈↓ πλ*[x;*[y;z]]
␈↓ ↓H␈↓We␈αnow␈αgive␈αan␈αinductive␈αdefinition␈αof␈αthe␈αset␈αof␈αpolynomials␈αwe␈αwish␈αto␈αconsider.␈αThe␈αdefinition
␈↓ ↓H␈↓will involve an inductive definition of terms.
␈↓ ↓H␈↓␈↓↓1.␈↓ Any term is a polynomial.
␈↓ ↓H␈↓␈↓↓2.␈↓ If p␈↓β1␈↓ and p␈↓β2␈↓ are polynomials then the "sum" of p␈↓β1␈↓ and p␈↓β2␈↓ is a polynomial.
␈↓ ↓H␈↓␈↓↓2.3␈↓ 9Differentiation 55␈↓
␈↓ ↓H␈↓where:
␈↓ ↓H␈↓␈↓↓1.␈↓ constants and variables are terms.
␈↓ ↓H␈↓␈↓↓2.␈↓ If t␈↓β1␈↓ and t␈↓β2␈↓ are terms then the "product" of t␈↓β1␈↓ and t␈↓β2␈↓ is a term.
␈↓ ↓H␈↓␈↓↓3.␈↓ If t␈↓β1␈↓ is a variable and t␈↓β2␈↓ is a constant then "t␈↓β1␈↓ raised to the t␈↓β2␈↓␈↓πth␈↓ power" is a term.
␈↓ ↓H␈↓␈↓↓4.␈↓ If t␈↓β1␈↓ is a term then "minus" t␈↓β1␈↓ is a term.
␈↓ ↓H␈↓We now give a BNF description of the above set using the syntax of prefix notation:
␈↓ ↓H␈↓<poly>␈↓ βλ::= <term> | <plus>[<poly>;<poly>]
␈↓ ↓H␈↓<term>␈↓ βλ::= <constant> | <variable> | <times>[<term>;<term>] | <expt>[<variable>;<constant>]
␈↓ ↓H␈↓␈↓ βλ::= <minus><term>
␈↓ ↓H␈↓<constant>␈↓ βλ::= <numeral>
␈↓ ↓H␈↓<plus>␈↓ βλ::= +
␈↓ ↓H␈↓<times>␈↓ βλ::= *
␈↓ ↓H␈↓<expt>␈↓ βλ::= ↑
␈↓ ↓H␈↓<minus>␈↓ βλ::= -
␈↓ ↓H␈↓<variable>␈↓ βλ::= <identifier>
␈↓ ↓H␈↓It␈α∂is␈α∂easy␈α∞to␈α∂write␈α∂recursive␈α∞algorithms␈α∂in␈α∂LISP;␈α∂the␈α∞only␈α∂problem␈α∂here␈α∞is␈α∂that␈α∂the␈α∂domain␈α∞and
␈↓ ↓H␈↓range␈α⊗of␈α∃LISP␈α⊗functions␈α∃is␈α⊗S-exprs,␈α∃not␈α⊗the␈α∃polynomials.␈α⊗ We␈α∃need␈α⊗to␈α⊗represent␈α∃arbitrary
␈↓ ↓H␈↓polynomials as S-exprs. We will do the representation in lists rather than S-exprs.
␈↓ ↓H␈↓Let␈α␈↓
R␈↓␈αbe␈αa␈αfunction␈αmapping␈αpolynomals␈αto␈αtheir␈αrepresentation␈αsuch␈αthat␈αa␈αvariable␈αis␈αmapped␈α
to
␈↓ ↓H␈↓its uppercase counterpart in the vocabulary of LISP atoms. Thus:
␈↓ ↓H␈↓␈↓ ∧x␈↓
R␈↓∞(␈↓<variable>␈↓∞)␈↓ = <literal atom>.
␈↓ ↓H␈↓Let constants (numerals), be just the LISP numerals; these are also respectable LISP atoms. Thus:
␈↓ ↓H␈↓␈↓ ¬␈↓
R␈↓␈↓∞(␈↓<numeral>␈↓∞)␈↓ = <numeral>.
␈↓ ↓H␈↓We␈α∞have␈α
now␈α∞specified␈α
a␈α∞representation␈α
for␈α∞the␈α
base␈α∞domains␈α
of␈α∞the␈α
inductive␈α∞definition␈α∞of␈α
our
␈↓ ↓H␈↓␈↓↓56 Applications␈↓ 52.3␈↓
␈↓ ↓H␈↓polynomials.␈α→It␈α→is␈α_time␈α→to␈α→develop␈α_the␈α→termination␈α→cases␈α_for␈α→the␈α→recursive␈α→definition␈α_of
␈↓ ↓H␈↓differentiation.
␈↓ ↓H␈↓We know from differential calculus that if ␈↓αu␈↓ is a constant or a variable then:
␈↓ ↓H␈↓␈↓ αXd␈↓αu␈↓/d␈↓αx␈↓ =␈↓ βx1 if ␈↓αx = u
␈↓ ↓H␈↓α␈↓ αX␈↓ βx␈↓0 otherwise
␈↓ ↓H␈↓We␈α
will␈α
represent␈α
the␈α∞d-operator␈α
as␈α
a␈α
binary␈α
LISP␈α∞function␈α
named␈α
␈↓αdiff␈↓.␈α
The␈α∞application,␈α
d␈↓αu␈↓/d␈↓αx␈↓
␈↓ ↓H␈↓will␈α
be␈α
represented␈α
as␈α∞␈↓αdiff[u;x]␈↓.␈α
Since␈α
constants␈α
and␈α
variables␈α∞are␈α
both␈α
represented␈α
as␈α∞atoms,␈α
we
␈↓ ↓H␈↓can␈α∂check␈α∂for␈α∂both␈α∂of␈α∂these␈α∂cases␈α∂by␈α∂using␈α∂the␈α∂predicate␈α∂␈↓αisindiv␈↓.␈α∂ Thus␈α∂a␈α∂representation␈α⊂of␈α∂the
␈↓ ↓H␈↓termination cases might be:
␈↓ ↓H␈↓␈↓ αX␈↓αdiff[u;x] <= [isindiv[u] → [eq[x;u] → 1; ␈↓
t␈↓α → 0] ... ]␈↓
␈↓ ↓H␈↓Notice␈α∂we␈α∂write␈α∂the␈α∂abbreviation,␈α∂␈↓αisindiv␈↓␈α∂instead␈α∂of␈α∂␈↓αisindiv␈↓βr␈↓.␈α∂ You␈α∂should␈α∂be␈α∂a␈α∂bit␈α∂wary␈α∂of␈α∞our
␈↓ ↓H␈↓definition already: ␈↓αdiff[1;1]␈↓ will evaluate to ␈↓α1␈↓.
␈↓ ↓H␈↓Now␈α∞that␈α
we␈α∞have␈α∞covered␈α
the␈α∞termination␈α∞case,␈α
what␈α∞can␈α
be␈α∞done␈α∞for␈α
the␈α∞representation␈α∞of␈α
the
␈↓ ↓H␈↓remaining class of terms and polynomials? That is, how should we represent sums and products?
␈↓ ↓H␈↓First, we will represent the operations *, +, -, and ↑ as atoms:
␈↓ ↓H␈↓␈↓ ¬H␈↓
R␈↓␈↓∞(␈↓ + ␈↓∞)␈↓ = ␈↓αPLUS␈↓
␈↓ ↓H␈↓␈↓ ¬H␈↓
R␈↓␈↓∞(␈↓ * ␈↓∞)␈↓ = ␈↓αTIMES␈↓
␈↓ ↓H␈↓␈↓ ¬H␈↓
R␈↓␈↓∞(␈↓ - ␈↓∞)␈↓ = ␈↓αMINUS␈↓
␈↓ ↓H␈↓␈↓ ¬H␈↓
R␈↓␈↓∞(␈↓ ↑ ␈↓∞)␈↓ = ␈↓αEXPT␈↓
␈↓ ↓H␈↓We␈α↔will␈α↔now␈α↔extend␈α↔the␈α↔mapping␈α↔␈↓
R␈↓␈α⊗to␈α↔occurrences␈α↔of␈α↔binary␈α↔operators␈α↔by␈α↔mapping␈α⊗to
␈↓ ↓H␈↓three-element lists:
␈↓ ↓H␈↓␈↓ ∧$␈↓
R␈↓␈↓∞(␈↓α ␈↓λα␈↓α[␈↓λβ␈↓β1␈↓α;␈↓λβ␈↓β2␈↓α] ␈↓∞)␈↓ = ␈↓α(␈↓
R␈↓∞(␈↓λα␈↓∞)␈↓α, ␈↓
R␈↓∞(␈↓λβ␈↓β1␈↓∞)␈↓, ␈↓
R␈↓∞(␈↓λβ␈↓β2␈↓∞)␈↓α).
␈↓ ↓H␈↓Unary applications will result in two-element lists:
␈↓ ↓H␈↓␈↓ ¬↓␈↓
R␈↓␈↓∞(␈↓α ␈↓λα␈↓α[␈↓λβ␈↓α] ␈↓∞)␈↓ = ␈↓α(␈↓
R␈↓∞(␈↓λα␈↓∞)␈↓α, ␈↓
R␈↓∞(␈↓λβ␈↓∞)␈↓α).
␈↓ ↓H␈↓For example:␈↓ ¬␈↓
R␈↓∞(␈↓α +[x; 2] ␈↓∞)␈↓ = ␈↓α(PLUS X 2)␈↓.
␈↓ ↓H␈↓A more complicated example: the polynomial,
␈↓ ↓H␈↓α␈↓ εβx␈↓π2␈↓α + 2yz + u
␈↓ ↓H␈↓will be translated to the following prefix notation:
␈↓ ↓H␈↓α␈↓ ¬β+[↑[x;2]; +[*[2;*[y;z]]; u]] ␈↓π 44␈↓α
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓α␈↓π 44␈↓α␈α∂␈↓This␈α∂is␈α∂messier␈α∂than␈α∂it␈α∂really␈α∂needs␈α∂to␈α∂be␈α∂because␈α∂we␈α∂assume␈α∂that␈α∂+␈α∂and␈α∂*␈α∂are␈α∂binary.␈α∞You
␈↓ ↓H␈↓should␈α⊂also␈α⊂notice␈α⊂that␈α⊂our␈α⊂␈↓
R␈↓-mapping␈α⊂is␈α⊃applicable␈α⊂to␈α⊂a␈α⊂larger␈α⊂class␈α⊂of␈α⊂expressions␈α⊃than␈α⊂just
␈↓ ↓H␈↓<poly>. Look at ␈↓α(x + y)*(z + 2).
␈↓ ↓H␈↓␈↓↓2.3␈↓ 9Differentiation 57␈↓
␈↓ ↓H␈↓From this it's easy to get the list form:
␈↓ ↓H␈↓α␈↓ βD(PLUS (EXPT X 2) (PLUS (TIMES 2 (TIMES Y Z)) U))
␈↓ ↓H␈↓Now we can complete the differentiation algorithm for + and *. We know:
␈↓ ↓H␈↓␈↓ αXd[␈↓αf + g␈↓]/d␈↓αx␈↓ = d␈↓αf/␈↓d␈↓αx + ␈↓d␈↓αg␈↓/d␈↓αx.
␈↓ ↓H␈↓We would see:␈↓ ∧'␈↓αu = ␈↓
R␈↓∞(␈↓α f + g ␈↓∞)␈↓ = ␈↓α(PLUS, ␈↓
R␈↓∞(␈↓α f ␈↓∞)␈↓α, ␈↓
R␈↓∞( ␈↓αg ␈↓∞)␈↓α)␈↓
␈↓ ↓H␈↓where:␈↓ αX␈↓αsecond[u] = ␈↓
R␈↓∞( ␈↓αf ␈↓∞)␈↓ and, ␈↓α ␈↓ ε(third[u] = ␈↓
R␈↓∞(␈↓α g ␈↓∞)␈↓. ␈↓π 45␈↓
␈↓ ↓H␈↓The result of differentiating ␈↓αu␈↓ is to be a new list of three elements:
␈↓ ↓H␈↓␈↓ αX1. the symbol ␈↓αPLUS␈↓.
␈↓ ↓H␈↓␈↓ αX2. the effect of ␈↓αdiff␈↓ operating ␈↓
R␈↓∞( ␈↓αf ␈↓∞)␈↓
␈↓ ↓H␈↓␈↓ αX3. the effect of ␈↓αdiff␈↓ operating ␈↓
R␈↓∞( ␈↓αg ␈↓∞)␈↓
␈↓ ↓H␈↓Thus another part of the algorithm:
␈↓ ↓H␈↓α␈↓ αXeq [first[u];PLUS] →␈↓ ∧xlist [PLUS; diff[second[u];x];diff[third[u];x]].
␈↓ ↓H␈↓α␈↓.
␈↓ ↓H␈↓d[␈↓αf*g]␈↓/d␈↓αx␈↓ is defined to be ␈↓αf* ␈↓d␈↓αg␈↓/d␈↓αx + g *␈↓d␈↓αf/␈↓d␈↓αx␈↓.
␈↓ ↓H␈↓So here's another part of ␈↓αdiff␈↓:
␈↓ ↓H␈↓α␈↓ αXeq[first[u];TIMES] →␈↓ ∧xlist[PLUS;
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧x list[TIMES; second[u];diff [third[u];x]];
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧x list[TIMES;third[u];diff [second[u];x]]]
␈↓ ↓H␈↓Finally, here's an example. We know:
␈↓ ↓H␈↓␈↓ ¬Kd[␈↓αx*y + x]␈↓/d␈↓αx = y + 1␈↓
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 45␈↓␈α
As␈α
we␈α
intimated␈α
earlier,␈α
we␈α
have␈α
entered␈αan␈α
unwise␈α
course␈α
here.␈α
We␈α
have␈α
tied␈α
the␈αalgorithm␈α
for
␈↓ ↓H␈↓symbolic␈α∞differentiation␈α∞to␈α∞a␈α∞specific␈α∞representation␈α∞for␈α∞polynomials.␈α∞Believing␈α∞that␈α∞much␈α∂can␈α∞be
␈↓ ↓H␈↓learned␈αfrom␈αseeing␈αmistakes,␈αwe␈αwill␈αuse␈αthat␈αrepresentation,␈αand␈αon␈αpage 59␈αwe␈αwill␈αexamine␈αour
␈↓ ↓H␈↓decision.
␈↓ ↓H␈↓␈↓↓58 Applications␈↓ 52.3␈↓
␈↓ ↓H␈↓Try: ␈↓α
␈↓ ↓H␈↓αdiff [(PLUS (TIMES X Y) X); X]
␈↓ ↓H␈↓α␈↓ αX=list [PLUS; diff[(TIMES X Y); X]; diff [X;X]]
␈↓ ↓H␈↓α␈↓ αX=list [PLUS;
␈↓ ↓H␈↓α␈↓ αX␈↓ β(list [PLUS;
␈↓ ↓H␈↓α␈↓ αX␈↓ β(␈↓ βhlist [TIMES; X; diff [Y;X]];
␈↓ ↓H␈↓α␈↓ αX␈↓ β(␈↓ βhlist [TIMES; Y; diff [X;X]]];
␈↓ ↓H␈↓α␈↓ αX␈↓ β(diff [X;X]]
␈↓ ↓H␈↓α␈↓ αX=list [PLUS;
␈↓ ↓H␈↓α␈↓ αX␈↓ β(list [PLUS;
␈↓ ↓H␈↓α␈↓ αX␈↓ β(␈↓ βhlist [TIMES; X ;0];
␈↓ ↓H␈↓α␈↓ αX␈↓ β(␈↓ βhlist [TIMES; Y;1]];
␈↓ ↓H␈↓α␈↓ αX␈↓ β(1 ]
␈↓ ↓H␈↓α␈↓ αX=(PLUS (PLUS (TIMES X 0) (TIMES Y 1)) 1)
␈↓ ↓H␈↓α␈↓which can be interpreted as:
␈↓ ↓H␈↓␈↓α␈↓ ¬qx*0 + y*1 + 1 . ␈↓
␈↓ ↓H␈↓Now␈α
it␈α
is␈α
clear␈α
that␈α
we␈α
have␈α
the␈α
right␈α
answer;␈α
it␈α
is␈α
equally␈α
clear␈α
that␈α
the␈α
representation␈αleaves␈α
much
␈↓ ↓H␈↓to␈α∞be␈α
desired.␈α∞There␈α
are␈α∞obvious␈α
simplifications␈α∞which␈α
we␈α∞would␈α
expect␈α∞to␈α
have␈α∞done␈α∞before␈α
we
␈↓ ↓H␈↓would␈α⊂consider␈α⊂this␈α⊂output␈α⊂acceptable.␈α⊂This␈α∂example␈α⊂is␈α⊂a␈α⊂particularly␈α⊂simple␈α⊂case␈α⊂for␈α∂algebraic
␈↓ ↓H␈↓simplification.␈α
We␈αcan␈α
easily␈αwrite␈α
a␈αLISP␈α
program␈αto␈α
perform␈αsimplifications␈α
like␈α
those␈αexpected
␈↓ ↓H␈↓here:␈α∂like␈α∂replacing␈α∂␈↓α0*x␈↓␈α∂by␈α∂␈↓α0␈↓,␈α∂and␈α∂␈↓αx*1␈↓␈α∂by␈α∂␈↓αx␈↓.␈α∂But␈α∂the␈α∂general␈α∂problem␈α∂of␈α∂writing␈α⊂simplifiers,␈α∂or
␈↓ ↓H␈↓indeed␈α⊂of␈α∂recognizing␈α⊂what␈α⊂is␈α∂a␈α⊂simplification,␈α⊂is␈α∂quite␈α⊂difficult.␈α⊂ A␈α∂whole␈α⊂branch␈α⊂of␈α∂computer
␈↓ ↓H␈↓science␈α⊂has␈α⊂grown␈α⊂up␈α⊃around␈α⊂symbolic␈α⊂and␈α⊂algebraic␈α⊃manipulation␈α⊂of␈α⊂expressions.␈α⊂One␈α⊃of␈α⊂the
␈↓ ↓H␈↓crucial␈α
parts␈αof␈α
such␈α
an␈αendeavor␈α
is␈αa␈α
sophisticated␈α
simplifier.␈α For␈α
more␈αdetails␈α
and␈α
examples␈αof
␈↓ ↓H␈↓the power of such systems see [Hea 68], [MAC 74], or [Mos 74].
␈↓ ↓H␈↓␈↓ ¬q␈↓↓Points to note␈↓
␈↓ ↓H␈↓This␈αproblem␈αof␈αrepresentation␈αis␈αtypical␈αof␈αdata␈αstructure␈αalgorithms␈αregardless␈αof␈αwhat␈αlanguage
␈↓ ↓H␈↓you␈α∂use.␈α∂ That␈α∂is,␈α∂once␈α∞you␈α∂have␈α∂decided␈α∂what␈α∂the␈α∞informal␈α∂algorithm␈α∂is,␈α∂pick␈α∂a␈α∞representation
␈↓ ↓H␈↓which␈α∃makes␈α∃your␈α∀algorithms␈α∃clean.␈α∃Examine␈α∀the␈α∃interplay␈α∃between␈α∀the␈α∃algorithm␈α∃and␈α∀the
␈↓ ↓H␈↓representation,␈α→and␈α→continue␈α→to␈α→examine␈α→your␈α→decisions␈α→as␈α→you␈α→refine␈α→your␈α~method.␈α→ In
␈↓ ↓H␈↓Section 2.5␈α∞we␈α∞will␈α∂see␈α∞a␈α∞series␈α∂of␈α∞representations,␈α∞each␈α∞becoming␈α∂more␈α∞and␈α∞more␈α∂"efficient"␈α∞and
␈↓ ↓H␈↓each requiring more "knowledge" being built into the algorithm.
␈↓ ↓H␈↓␈↓↓2.3␈↓ 9Differentiation 59␈↓
␈↓ ↓H␈↓Here's the ␈↓αdiff␈↓ algorithm for + and *. ␈↓α
␈↓ ↓H␈↓αdiff[u;x] <=
␈↓ ↓H␈↓α␈↓ αX[isindiv[u] → [eq [x;u] → 1; ␈↓
t␈↓α → 0];
␈↓ ↓H␈↓α␈↓ αX eq [first [u]; PLUS] → list␈↓ ¬H[PLUS;
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬H diff [second [u]; x];
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬H diff [third [u]; x]];
␈↓ ↓H␈↓α␈↓ αX eq [first[u]; TIMES] → list␈↓ ¬H[PLUS;
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬H list␈↓ ελ[TIMES;
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬H␈↓ ελ second[u];
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬H␈↓ ελ diff [third [u]; x]];
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬H list␈↓ ελ[TIMES;
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬H␈↓ ελ third [u];
␈↓ ↓H␈↓α␈↓ αX␈↓ ¬H␈↓ ελ diff [second[u]; x]]];
␈↓ ↓H␈↓α␈↓ αX ␈↓
t␈↓α → ␈↓λB␈↓α]
␈↓ ↓H␈↓As␈α⊂we␈α⊂mentioned␈α∂earlier,␈α⊂the␈α⊂current␈α⊂manifestation␈α∂of␈α⊂␈↓αdiff␈↓␈α⊂encodes␈α∂too␈α⊂much␈α⊂of␈α⊂our␈α∂particular
␈↓ ↓H␈↓representation␈αfor␈αpolynomials.␈αThe␈αseparation␈αof␈αalgorithm␈αfrom␈αrepresentation␈αis␈αbeneficial␈αfrom
␈↓ ↓H␈↓at␈α∩least␈α∩two␈α∩standpoints.␈α∩ First,␈α∩changing␈α⊃representation␈α∩should␈α∩have␈α∩a␈α∩minimal␈α∩effect␈α∩on␈α⊃the
␈↓ ↓H␈↓structure␈α∞of␈α∞the␈α∞algorithm,␈α
but␈α∞␈↓αdiff␈↓␈α∞␈↓↓knows␈↓␈α∞that␈α
variables␈α∞are␈α∞represented␈α∞as␈α
atoms␈α∞and␈α∞a␈α∞sum␈α
is
␈↓ ↓H␈↓represented␈αas␈αa␈αlist␈αwhose␈α␈↓αfirst␈↓-part␈αis␈α␈↓αPLUS␈↓.␈α Second,␈αreadability␈αof␈αthe␈αalgorithm␈αsuffers␈αgreatly.
␈↓ ↓H␈↓How␈α∂much␈α∞of␈α∂␈↓αdiff␈↓␈α∞really␈α∂needs␈α∞to␈α∂know␈α∞about␈α∂the␈α∞representation␈α∂and␈α∞how␈α∂can␈α∞we␈α∂improve␈α∞the
␈↓ ↓H␈↓readability of ␈↓αdiff␈↓?
␈↓ ↓H␈↓The␈α
uses␈α
of␈α
␈↓αfirst␈↓,␈α
␈↓αsecond␈↓,␈α
and␈α
␈↓αthird␈↓␈α
are␈α
not␈α
particularly␈α
mnemonic␈↓π 46␈↓.␈α
We␈α
used␈α
␈↓αsecond␈↓␈α
to␈α
get␈αthe␈α
first
␈↓ ↓H␈↓argument␈α∂to␈α⊂a␈α∂sum␈α⊂or␈α∂product␈α⊂and␈α∂used␈α⊂␈↓αthird␈↓␈α∂to␈α∂get␈α⊂the␈α∂second.␈α⊂ We␈α∂used␈α⊂␈↓αfirst␈↓␈α∂to␈α⊂extract␈α∂the
␈↓ ↓H␈↓operator.
␈↓ ↓H␈↓Let's define the selectors:
␈↓ ↓H␈↓α␈↓ ¬hop[x] <= first[x]
␈↓ ↓H␈↓α␈↓ ¬Narg␈↓β1␈↓α[x] <= second[x]
␈↓ ↓H␈↓α␈↓ ¬Warg␈↓β2␈↓α[x] <= third[x]
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 46␈↓ However, they are more readable than ␈↓αcar-cdr␈↓-chains.
␈↓ ↓H␈↓␈↓↓60 Applications␈↓ 52.3␈↓
␈↓ ↓H␈↓Then ␈↓αdiff␈↓ becomes:
␈↓ ↓H␈↓αdiff[u;x] <=␈↓ βλ[isindiv[u] → [eq [x;u] → 1; ␈↓
t␈↓α → 0];
␈↓ ↓H␈↓α␈↓ βλ eq [op[u]; PLUS] → list␈↓ ¬h[PLUS;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬h diff [arg␈↓β1␈↓α [u]; x];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬h diff [arg␈↓β2␈↓α [u]; x]];
␈↓ ↓H␈↓α␈↓ βλ eq [op[u]; TIMES] → list␈↓ ¬h[PLUS;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬h list␈↓ ε([TIMES;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬h␈↓ ε( arg␈↓β1␈↓α [u];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬h␈↓ ε( diff [arg␈↓β2␈↓α [u]; x]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬h list␈↓ ε([TIMES;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬h␈↓ ε( arg␈↓β2␈↓α [u];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬h␈↓ ε( diff [arg␈↓β1␈↓α [u]; x]]];
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α → ␈↓λB␈↓α]
␈↓ ↓H␈↓Still,␈αthere␈αis␈αmuch␈αof␈αthe␈αrepresentation␈α
present.␈αRecognition␈αof␈αvariables␈αand␈αother␈αterms␈α
can␈αbe
␈↓ ↓H␈↓abstracted.␈αWe␈αneed␈αonly␈αrecognize␈αwhen␈αa␈αterm␈αis␈αa␈αsum,␈αa␈αproduct,␈αa␈αvariable␈αor␈αa␈αconstant.␈α To
␈↓ ↓H␈↓test␈αfor␈αthe␈αoccurrence␈αof␈α
a␈αnumeral␈αwe␈αshall␈αassume␈α
a␈αunary␈αLISP␈αpredicate␈αcalled␈α␈↓αnumberp␈↓␈α
which
␈↓ ↓H␈↓returns␈α∀␈↓
t␈↓␈α∀just␈α∀in␈α∀the␈α∀case␈α∀that␈α∀its␈α∀argument␈α∀is␈α∀a␈α∀numeral.␈α∀ Then,␈α∀in␈α∀terms␈α∀of␈α∀the␈α∀current
␈↓ ↓H␈↓representation, we could define such recognizers and predicates as:
␈↓ ↓H␈↓α␈↓ ¬≠issum[x] <= eq[op[x];PLUS]
␈↓ ↓H␈↓α␈↓ ¬∞isprod[x] <= eq[op[x];TIMES]
␈↓ ↓H␈↓α␈↓ ¬2isconst[x] <= numberp[x]
␈↓ ↓H␈↓α␈↓ ∧*isvar[x] <= [isindiv[x] → not[isconst[x]]; ␈↓
t␈↓α → ␈↓
f␈↓α]
␈↓ ↓H␈↓α␈↓ ¬=samevar[x;y] <= eq[x;y]
␈↓ ↓H␈↓␈↓↓2.3␈↓ 9Differentiation 61␈↓
␈↓ ↓H␈↓Now we can rewrite ␈↓αdiff␈↓ as:
␈↓ ↓H␈↓αdiff[u;x] <=␈↓ βλ[isvar[u] → [samevar[x;u] → 1; ␈↓
t␈↓α → 0];
␈↓ ↓H␈↓α␈↓ βλ isconst[u] → 0;
␈↓ ↓H␈↓α␈↓ βλ issum[u] → list␈↓ ∧X[PLUS;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧X diff [arg␈↓β1␈↓α[u]; x];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧X diff [arg␈↓β2␈↓α[u]; x]];
␈↓ ↓H␈↓α␈↓ βλ isprod[u] → list␈↓ ∧X[PLUS;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧X list␈↓ ¬_[TIMES;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧X␈↓ ¬_ arg␈↓β1␈↓α[u];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧X␈↓ ¬_ diff [arg␈↓β2␈↓α[u]; x]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧X list␈↓ ¬_[TIMES;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧X␈↓ ¬_ arg␈↓β2␈↓α[u];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧X␈↓ ¬_ diff [arg␈↓β1␈↓α[u]; x]]];
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α → ␈↓λB␈↓α]
␈↓ ↓H␈↓Readability␈α
is␈α
certainly␈α
improving,␈α
but␈α
the␈α
representation␈αis␈α
still␈α
known␈α
to␈α
␈↓αdiff␈↓.␈α
When␈α
we␈αbuild␈α
the
␈↓ ↓H␈↓result␈α
of␈α
the␈α∞sum␈α
or␈α
product␈α
of␈α∞derivatives␈α
we␈α
use␈α
knowledge␈α∞of␈α
the␈α
representation.␈α
It␈α∞would␈α
be
␈↓ ↓H␈↓better to define:
␈↓ ↓H␈↓α␈↓ ¬↓makesum[x;y] <= list[PLUS;x;y]
␈↓ ↓H␈↓α␈↓ ∧smakeprod[x;y] <= list[TIMES;x;y]
␈↓ ↓H␈↓Then the new ␈↓αdiff␈↓ is:
␈↓ ↓H␈↓αdiff[u;x] <=␈↓ βλ[isvar[u] → [samevar[x;u] → 1; ␈↓
t␈↓α → 0];
␈↓ ↓H␈↓α␈↓ βλ isconst[u] → 0;
␈↓ ↓H␈↓α␈↓ βλ issum[u] → makesum[␈↓ ¬(diff[arg␈↓β1␈↓α[u]; x];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬(diff[arg␈↓β2␈↓α[u]; x]];
␈↓ ↓H␈↓α␈↓ βλ isprod[u] → makesum[␈↓ ¬(makeprod[␈↓ ε(arg␈↓β1␈↓α[u];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬(␈↓ ε(diff[arg␈↓β2␈↓α[u]; x]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬(makeprod[␈↓ ε(arg␈↓β2␈↓α[u];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ¬(␈↓ ε(diff [arg␈↓β1␈↓α[u]; x]]];
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α → ␈↓λB␈↓α]
␈↓ ↓H␈↓In␈α∞the␈α
process,␈α∞␈↓αdiff␈↓␈α
has␈α∞become␈α
much␈α∞more␈α
understandable␈α∞and,␈α
more␈α∞importantly,␈α
the␈α∞details␈α
of
␈↓ ↓H␈↓the␈α∂representation␈α∞have␈α∂been␈α∂relegated␈α∞to␈α∂subfunctions.␈α∞Changing␈α∂representation␈α∂simply␈α∞requires
␈↓ ↓H␈↓supplying␈α
different␈α
subfunctions.␈αNo␈α
changes␈α
need␈αbe␈α
made␈α
to␈α␈↓αdiff␈↓.␈α
There␈α
has␈αonly␈α
been␈α
a␈αslight
␈↓ ↓H␈↓decrease␈α∞in␈α∞efficiency.␈α∞ The␈α∞termination␈α
condition␈α∞in␈α∞the␈α∞original␈α∞␈↓αdiff␈↓␈α
is␈α∞a␈α∞bit␈α∞more␈α∞succinct,␈α
but
␈↓ ↓H␈↓incorrect.␈α Looking␈α
back,␈αfirst␈α
we␈αabstracted␈αthe␈α
selector␈αfunctions:␈α
those␈αwhich␈αselected␈α
components;
␈↓ ↓H␈↓next␈α∂we␈α∂abstracted␈α∂the␈α∂recognizers:␈α∂the␈α∂predicates␈α∂indicating␈α∂which␈α∂term␈α∂was␈α∂present;␈α∂finally␈α∞we
␈↓ ↓H␈↓modified␈α∪the␈α∪constructors:␈α∩the␈α∪functions␈α∪which␈α∩make␈α∪new␈α∪terms.␈α∩ These␈α∪three␈α∪components␈α∩of
␈↓ ↓H␈↓programming:␈αselectors,␈α
recognizers,␈αand␈α
constructors,␈αwill␈αappear␈α
again␈αon␈α
page 150␈αin␈αa␈α
discussion
␈↓ ↓H␈↓of McCarthy's abstract syntax.
␈↓ ↓H␈↓␈↓↓62 Applications␈↓ 52.3␈↓
␈↓ ↓H␈↓The␈α∂␈↓αdiff␈↓␈α∞algorithm␈α∂is␈α∞abstract␈α∂now,␈α∞in␈α∂the␈α∂sense␈α∞that␈α∂the␈α∞representation␈α∂of␈α∞the␈α∂domain␈α∂and␈α∞the
␈↓ ↓H␈↓representation␈αof␈αthe␈αfunctions␈αand␈αpredicates␈αwhich␈αmanipulate␈αthat␈αdomain␈αhave␈αbeen␈αextracted
␈↓ ↓H␈↓out.␈α∂This␈α∞is␈α∂our␈α∞␈↓λr␈↓-mapping␈α∂again;␈α∞we␈α∂mapped␈α∞the␈α∂domain␈α∞of␈α∂<poly>'s␈α∞to␈α∂lists␈α∞and␈α∂mapped␈α∞the
␈↓ ↓H␈↓constructors,␈α∞selectors,␈α∞and␈α∞recognizers␈α∞to␈α∞list-manipulating␈α
functions.␈α∞ Thus␈α∞the␈α∞data␈α∞types␈α∞of␈α
the
␈↓ ↓H␈↓arguments␈α
␈↓αu␈↓␈α
and␈α
␈↓αx␈↓␈α∞are␈α
<poly>␈α
and␈α
<var>␈α∞respectively,␈α
␈↓↓not␈↓␈α
list␈α
and␈α∞atom.␈α
To␈α
stress␈α
this␈α∞point␈α
we
␈↓ ↓H␈↓should␈αmake␈αone␈αmore␈αtransformation␈αon␈α␈↓αdiff␈↓.␈αWe␈αhave␈αfrequently␈αsaid␈αthat␈αthere␈αis␈αa␈αsubstantial
␈↓ ↓H␈↓parallel␈α∂between␈α∂a␈α⊂data␈α∂structure␈α∂and␈α⊂the␈α∂algorithms␈α∂which␈α⊂manipulate␈α∂it.␈α∂Paralleling␈α⊂the␈α∂BNF
␈↓ ↓H␈↓definition of <poly> on page 55, we write:
␈↓ ↓H␈↓αdiff[u;x] <=␈↓ αx[isterm[u] → diffterm[u;x];
␈↓ ↓H␈↓α␈↓ αx issum[u] → makesum[␈↓ ¬_diff[arg␈↓β1␈↓α[u]; x];
␈↓ ↓H␈↓α␈↓ αx␈↓ ¬_diff[arg␈↓β2␈↓α[u]; x]];
␈↓ ↓H␈↓α␈↓ αx ␈↓
t␈↓α → ␈↓λB␈↓α]
␈↓ ↓H␈↓αdiffterm[u;x] <=␈↓ β8[isconst[u] → 0;
␈↓ ↓H␈↓α␈↓ β8 isvar[u] → [samevar[x;u] → 1; ␈↓
t␈↓α → 0];
␈↓ ↓H␈↓α␈↓ β8 isprod[u] → makesum[␈↓ ¬Xmakeprod[␈↓ εharg␈↓β1␈↓α[u];
␈↓ ↓H␈↓α␈↓ β8␈↓ ¬X␈↓ εhdiff[arg␈↓β2␈↓α[u]; x]];
␈↓ ↓H␈↓α␈↓ β8␈↓ ¬Xmakeprod[␈↓ εharg␈↓β2␈↓α[u];
␈↓ ↓H␈↓α␈↓ β8␈↓ ¬X␈↓ εhdiff[arg␈↓β1␈↓α[u]; x]]];
␈↓ ↓H␈↓α␈↓ β8 ␈↓
t␈↓α → ␈↓λB␈↓α]
␈↓ ↓H␈↓To satisfy our complaint of page 56 that ␈↓αdiff[1; 1]␈↓ gives a defined result, we should also add:
␈↓ ↓H␈↓α␈↓ αXdiff␈↓λ'␈↓α[u; x] <= [␈↓ ∧_isvar[x] → [ispoly[u] → diff[u; x]]; ␈↓
t␈↓α → ␈↓λB␈↓α]
␈↓ ↓H␈↓Finally,␈α∀notice␈α∀that␈α∃our␈α∀abstraction␈α∀process␈α∀has␈α∃masked␈α∀the␈α∀order-dependence␈α∃of␈α∀conditional
␈↓ ↓H␈↓expressions. Exactly one of the recognizers will be satisfied by the form ␈↓αu␈↓.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓ Extend the version of ␈↓αdiff␈↓ of your choice to handle differentiation of powers such as ␈↓α↑[x; 3]␈↓.
␈↓ ↓H␈↓␈↓↓2.␈↓ Extend ␈↓αdiff␈↓ to handle unary minus.
␈↓ ↓H␈↓␈↓↓3.␈↓␈α⊃Extend␈α⊃␈↓αdiff␈↓␈α∩to␈α⊃handle␈α⊃differentiation␈α∩of␈α⊃the␈α⊃trigonometric␈α⊃functions,␈α∩␈↓αsin␈↓␈α⊃and␈α⊃␈↓αcos␈↓␈α∩and␈α⊃their
␈↓ ↓H␈↓composition with polynomials. For example it should handle ␈↓αsin␈↓π2␈↓αx + cos(x␈↓π3␈↓α + 5x -2)␈↓.
␈↓ ↓H␈↓␈↓↓4.␈↓ Write an algorithm to handle integration of polynomials.
␈↓ ↓H␈↓␈↓↓2.4␈↓ wData Bases 63␈↓
␈↓ ↓H␈↓␈↓ ¬j␈↓↓2.4 Data Bases␈↓
␈↓ ↓H␈↓One␈αof␈α
the␈αmore␈α
intriguing␈αapplications␈αof␈α
LISP␈αis␈α
in␈αthe␈αarea␈α
of␈αdata␈α
base␈αmanagement.␈α
In␈αthis
␈↓ ↓H␈↓section we introduce the ideas and suggest how LISP can be applied to the problems.
␈↓ ↓H␈↓A␈α
data␈α
base␈αis␈α
a␈α
collection␈αof␈α
objects␈α
together␈αwith␈α
a␈α
set␈αof␈α
functions␈α
to␈αpose␈α
questions␈α
about␈αthe
␈↓ ↓H␈↓objects␈α⊃in␈α⊃the␈α⊃base,␈α⊃to␈α⊃select␈α⊃objects␈α⊃from␈α⊃the␈α⊃base,␈α⊃and␈α⊃to␈α⊃construct␈α⊃new␈α⊃entries␈α⊃in␈α⊃the␈α⊂base.
␈↓ ↓H␈↓Expressed␈αdifferently,␈αa␈αdata␈α
base␈αis␈αan␈αabstract␈αdata␈α
structure.␈α We␈αneed␈αto␈αlocate␈α
information␈αin
␈↓ ↓H␈↓the␈α⊂base.␈α⊂ We␈α⊂should␈α⊂be␈α⊂able␈α⊂to␈α⊂ask␈α⊂the␈α⊂system␈α⊂for␈α⊂a␈α⊂specific␈α⊂object␈α⊂or␈α⊂we␈α⊂should␈α⊂be␈α⊃able␈α⊂to
␈↓ ↓H␈↓partially␈αspecify␈αour␈αrequest␈α("find␈αall␈αbooks␈αabout␈αLISP"␈αor␈α"find␈αall␈αbooks␈αabout␈αLISP␈αpublished
␈↓ ↓H␈↓before␈α∂1975").␈α∂ We␈α∂should␈α∞be␈α∂able␈α∂to␈α∂add␈α∞entries␈α∂and␈α∂delete␈α∂entries,␈α∞but␈α∂we␈α∂will␈α∂postpone␈α∞these
␈↓ ↓H␈↓kinds of requests until later.
␈↓ ↓H␈↓The␈αrepresentational␈αdetails␈αof␈αobjects␈αwill␈αbe␈αsuppressed␈αas␈αusual,␈αand␈αwe␈αwill␈αconcentrate␈α
on␈αthe
␈↓ ↓H␈↓abstract␈α
properties.␈α
In␈α
our␈α
first␈αexample,␈α
the␈α
objects␈α
in␈α
the␈αdata␈α
base␈α
will␈α
represent␈α
constants:␈αan
␈↓ ↓H␈↓object will have a name and a collection of properties and values.
␈↓"␈↓ ↓H␈↓
⊂αααααααπααααα⊃
␈↓"␈↓ ↓H␈↓
~ prop1 ~ val1~
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ
␈↓"␈↓ ↓H␈↓
~ prop2 ~ val2~
␈↓"␈↓ ↓H␈↓
# # #
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ
␈↓"␈↓ ↓H␈↓
~ propn ~ valn~
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααααα$
␈↓ ↓H␈↓␈↓ ¬)␈↓↓An object representation␈↓
␈↓ ↓H␈↓For␈α∞example,␈α∞a␈α∞data␈α∞base␈α∞dealing␈α∞with␈α∞business␈α∞supplies␈α∞might␈α∞have␈α∞objects␈α∞named␈α∞boxes.␈α
Each
␈↓ ↓H␈↓box has properties like size and contents.
␈↓ ↓H␈↓Not␈α∞all␈α∞objects␈α∞need␈α∞to␈α∞have␈α∞the␈α∞same␈α
number␈α∞of␈α∞properties.␈α∞For␈α∞example␈α∞in␈α∞a␈α∞data␈α∞base␈α
whose
␈↓ ↓H␈↓objects␈αare␈αbibliographic␈αreferences,␈αbooks␈αneed␈αnot␈αhave␈αpage␈αreferences,␈αwhereas␈αjournal␈αarticles
␈↓ ↓H␈↓require␈αthem;␈αjournal␈α
references␈αdon't␈αinclude␈α
a␈αpublisher␈αwhereas␈α
books␈αdo.␈α The␈αprograms␈α
which
␈↓ ↓H␈↓manipulate the data base must be structured to take changeablility into account.
␈↓ ↓H␈↓␈↓↓64 Applications␈↓ 22.4␈↓
␈↓ ↓H␈↓Here␈α∂are␈α⊂some␈α∂examples:␈α∂the␈α⊂first␈α∂one␈α∂was␈α⊂extracted␈α∂from␈α∂the␈α⊂side␈α∂of␈α∂a␈α⊂Xerox␈α∂paper␈α⊂box;␈α∂the
␈↓ ↓H␈↓second might be a representation of a bibliographic entry for this book.
␈↓"␈↓ ↓H␈↓
⊂αααααααπαααααααααααα⊃
␈↓"␈↓ ↓H␈↓
~ NAME ~ 4029258 ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ SIZE ~ 8-1/2 x 11 ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ COLOR ~ WHITE ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ AMNT ~ 10 REAMS ~
␈↓"␈↓ ↓H␈↓
%ααααααα∀αααααααααααα$
␈↓"␈↓ ↓H␈↓
⊂ααααααααπααααααααααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
~ AUTHOR ~ ALLEN, JOHN, R. ~
␈↓"␈↓ ↓H␈↓
εααααααααβαααααααααααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ TITLE ~ THE ANATOMY OF LISP ~
␈↓"␈↓ ↓H␈↓
εααααααααβαααααααααααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ TYPE ~ BOOK ~
␈↓"␈↓ ↓H␈↓
εααααααααβαααααααααααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ PUBL ~ MCGRAW-HILL ~
␈↓"␈↓ ↓H␈↓
εααααααααβαααααααααααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ DATE ~ 1977 ~
␈↓"␈↓ ↓H␈↓
%αααααααα∀ααααααααααααααααααααα$
␈↓ ↓H␈↓Given␈αa␈αdata␈α
base␈αof␈αobjects,␈α
we␈αneed␈αto␈αbe␈α
able␈αto␈αmanipulate␈α
these␈αobjects␈αin␈α
meaningful␈αways.
␈↓ ↓H␈↓We␈αwill␈αnot␈αaddress␈αthe␈αproblems␈αof␈α
designing␈αinput␈αand␈αoutput,␈αbut␈αwill␈αconcern␈α
ourselves␈αsolely
␈↓ ↓H␈↓with␈α∞the␈α∞problems␈α∂of␈α∞semantics␈α∞of␈α∂data␈α∞base␈α∞primitives:␈α∂how␈α∞can␈α∞we␈α∂use␈α∞the␈α∞information␈α∂in␈α∞the
␈↓ ↓H␈↓base?
␈↓ ↓H␈↓In␈αrequesting␈αinformation␈αfrom␈αa␈αdata␈αbase,␈αwe␈αtypically␈αspecify␈αpart␈αof␈αthe␈αrequest␈αand␈αexpect␈αthe
␈↓ ↓H␈↓system␈α∞to␈α∞come␈α
up␈α∞with␈α∞a␈α
set␈α∞of␈α∞possibilities␈α
which␈α∞fit␈α∞our␈α
description.␈α∞For␈α∞example,␈α∞the␈α
request:
␈↓ ↓H␈↓"find␈α
all␈αbooks␈α
about␈α
LISP",␈αspecifies␈α
that␈α
we␈αare␈α
interested␈α
only␈αin␈α
books,␈α
not␈αin␈α
journal␈αarticles␈α
or
␈↓ ↓H␈↓course␈αnotes;␈αthe␈αtopic␈αis␈αspecified␈αto␈αbe␈αLISP,␈α
but␈αthe␈αsystem␈αis␈αfree␈αto␈αselect␈αthe␈αother␈α
components:
␈↓ ↓H␈↓the␈αauthor,␈αthe␈αtitle,␈αthe␈αpublisher␈αand␈αthe␈αdate␈αof␈αpublication.␈αThe␈αobjects␈αwhich␈αare␈αspecified␈αare
␈↓ ↓H␈↓called␈α∩␈↓↓constants␈↓,␈α∩the␈α⊃unspecified␈α∩components␈α∩are␈α⊃␈↓↓variables␈↓.␈α∩ A␈α∩request␈α⊃is␈α∩a␈α∩structure␈α∩called␈α⊃a
␈↓ ↓H␈↓␈↓↓pattern␈↓␈αand␈αconsists␈αof␈αan␈αordered␈αcollection␈αof␈αconstants␈αand␈αvariables.␈α The␈αelements␈αin␈αthe␈αdata
␈↓ ↓H␈↓base␈αare␈αalso␈αpatterns;␈αfor␈αthis␈αexample,␈αthey␈αcontain␈αonly␈αconstants;␈αsuch␈αconstant␈αpatterns␈αare␈αalso
␈↓ ↓H␈↓called␈α
records.␈α
The␈α
process␈α
of␈α
discovering␈α
whether␈α
or␈α
not␈α
a␈α
record␈α
in␈α
the␈α
data␈α
base␈α∞matches␈α
the
␈↓ ↓H␈↓request is called ␈↓↓pattern matching␈↓.
␈↓ ↓H␈↓We␈αdescribe␈αa␈αsimple␈αpattern␈αmatcher␈αnamed␈α␈↓αmatch␈↓.␈αIt␈αexpects␈αtwo␈αarguments.␈αThe␈αfirst␈αargument
␈↓ ↓H␈↓is␈α
a␈αconstant␈α
pattern␈αcalled␈α
␈↓αpat␈↓.␈α The␈α
second␈α
argument,␈α␈↓αexp␈↓␈α
represents␈αa␈α
request;␈αit␈α
may␈αbe␈α
constant,
␈↓ ↓H␈↓or␈α
it␈α
may␈α
contain␈α∞variables.␈α
If␈α
it␈α
does␈α
contain␈α∞variables,␈α
then␈α
the␈α
pattern␈α
matching␈α∞process␈α
must
␈↓ ↓H␈↓establish␈α⊂a␈α∂match␈α⊂between␈α∂those␈α⊂variables␈α⊂and␈α∂components␈α⊂of␈α∂our␈α⊂data␈α∂base␈α⊂object.␈α⊂The␈α∂value
␈↓ ↓H␈↓returned␈α
by␈α
␈↓αmatch␈↓␈α∞will␈α
either␈α
represent␈α
the␈α∞associations␈α
built␈α
up␈α
to␈α∞match␈α
the␈α
constant␈α∞pattern␈α
to
␈↓ ↓H␈↓the expression, or the value returned will indicate failure if no match is possible.
␈↓ ↓H␈↓␈↓↓2.4␈↓ wData Bases 65␈↓
␈↓ ↓H␈↓Patterns␈αwill␈αbe␈αrepresented␈αas␈αlists␈αwith␈αatoms␈αrepresenting␈αconstants,␈αand␈αvariables␈αrepresented␈αas
␈↓ ↓H␈↓lower-case␈α∞greek␈α∞letters.␈α∞ We␈α∞will␈α∞represent␈α∞failure␈α∞by␈α
returning␈α∞the␈α∞atom␈α∞␈↓αNO␈↓.␈α∞In␈α∞the␈α∞case␈α∞that␈α
a
␈↓ ↓H␈↓match␈α∞is␈α∞possible,␈α∂we␈α∞will␈α∞return␈α∞a␈α∂list␈α∞of␈α∞pairs,␈α∂where␈α∞each␈α∞pair␈α∞is␈α∂a␈α∞variable␈α∞and␈α∂its␈α∞matching
␈↓ ↓H␈↓constant.
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓α␈↓ ∧amatch[(A (B C));(A (B ␈↓εa␈↓α))] = ((␈↓εa␈↓α C))
␈↓ ↓H␈↓α␈↓ ∧Pmatch[(A B C);(A ␈↓εa␈↓α ␈↓εb␈↓α)] = ((␈↓εa␈↓α B) (␈↓εb␈↓α C))
␈↓ ↓H␈↓α␈↓ ¬∞match[(A B C);(A C ␈↓εb␈↓α)] = NO
␈↓ ↓H␈↓Pattern matching can become quite complex. For example:
␈↓ ↓H␈↓α␈↓ βfmatch[(A (B C) (D C));(A (B ␈↓εa␈↓α) (␈↓εb␈↓α C))] = ((␈↓εa␈↓α C) (␈↓εb␈↓α D))
␈↓ ↓H␈↓α␈↓ ∧%match[(A (B C) (D C));(A (B ␈↓εa␈↓α) (␈↓εa␈↓α C))] = NO
␈↓ ↓H␈↓The␈α∂second␈α∞example␈α∂fails␈α∞since␈α∂once␈α∞we␈α∂have␈α∂associated␈α∞␈↓αC␈↓␈α∂with␈α∞␈↓εa␈↓␈α∂we␈α∞must␈α∂use␈α∂that␈α∞association
␈↓ ↓H␈↓throughout the rest of the pattern match; and ␈↓α(D C)␈↓ does not match ␈↓α(␈↓εa␈↓α C)␈↓ when ␈↓εa␈↓ denotes ␈↓αC␈↓␈↓π 47␈↓.
␈↓ ↓H␈↓We␈α∂will␈α∞write␈α∂␈↓αmatch␈↓␈α∞in␈α∂terms␈α∞of␈α∂a␈α∞subfunction␈α∂named␈α∞␈↓αmatch␈↓λ'␈↓.␈α∂ This␈α∞subfunction␈α∂carries␈α∂a␈α∞third
␈↓ ↓H␈↓argument,␈α␈↓αmlist␈↓,␈αwhich␈αrepresents␈αthe␈αlist␈αof␈αpartial␈αmatches.␈αWhenever␈αwe␈αlocate␈αa␈αvariable␈αin␈αthe
␈↓ ↓H␈↓expression,␈α∂we␈α∂examine␈α∂the␈α∂current␈α∞␈↓αmlist␈↓.␈α∂If␈α∂the␈α∂variable␈α∂appears,␈α∞then␈α∂we␈α∂must␈α∂check␈α∂its␈α∞entry
␈↓ ↓H␈↓against␈α⊂the␈α∂corresponding␈α⊂part␈α∂of␈α⊂the␈α∂pattern.␈α⊂If␈α∂the␈α⊂variable␈α∂does␈α⊂not␈α∂occur␈α⊂in␈α∂␈↓αmlist␈↓,␈α⊂then␈α∂we
␈↓ ↓H␈↓associate the variable with the appropriate part of the constant pattern.
␈↓ ↓H␈↓αmatch[pat;exp] <= match␈↓λ'␈↓α[pat;exp;( )]
␈↓ ↓H␈↓αmatch␈↓λ'␈↓α[pat;exp;mlist] <=␈↓ ∧_[equal[mlist;NO] → NO;
␈↓ ↓H␈↓α␈↓ ∧_ isconst[pat] → [sameconst[pat;exp] → ␈↓
t␈↓α; ␈↓
t␈↓α → NO];
␈↓ ↓H␈↓α␈↓ ∧_ isvar[pat] → check[pat;exp;lookup[pat;mlist];mlist];
␈↓ ↓H␈↓α␈↓ ∧_ ␈↓
t␈↓α → match␈↓λ'␈↓α[␈↓ ¬8suffix[pat];
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ¬8suffix[exp];
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ¬8match␈↓λ'␈↓α[prefix[pat];prefix[exp];mlist]]
␈↓ ↓H␈↓αcheck[var;exp;val;mlist] <=␈↓ ∧8[not[val] → concat[mkent[var;exp];mlist];
␈↓ ↓H␈↓α␈↓ ∧8 sameconst[exp;val] → mlist;
␈↓ ↓H␈↓α␈↓ ∧8 ␈↓
t␈↓α → NO]
␈↓ ↓H␈↓αlookup[var;l] <=␈↓ β8[null[l] → f;
␈↓ ↓H␈↓α␈↓ β8 samevar[var;name[first[l]]] → val[first[l]];
␈↓ ↓H␈↓α␈↓ β8 ␈↓
t␈↓α → lookup[var;rest[l]]]
␈↓ ↓H␈↓To␈αcomplete␈αour␈αdescription␈αof␈α␈↓αmatch␈↓␈αwe␈αshould␈αsupply␈αthe␈αdata␈αstructure␈αmanipulating␈αfunctions:
␈↓ ↓H␈↓␈↓αisconst␈↓,␈α
␈↓αisvar␈↓,␈α
␈↓αprefix␈↓,␈α
␈↓αsuffix␈↓,␈α
␈↓αsamevar␈↓,␈α
and␈α
␈↓αsameconst␈↓;␈αand␈α
␈↓αmkent␈↓,␈α
␈↓αname␈↓,␈α
and␈α
␈↓αval␈↓.␈α
The␈α
first␈α
five␈αare
␈↓ ↓H␈↓related,␈α
dealing␈αwith␈α
the␈αrepresentation␈α
of␈αpatterns;␈α
the␈α
final␈αthree␈α
involve␈αthe␈α
representation␈αof␈α
the
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 47␈↓ This assumes that the match proceeds in a left-to-right order.
␈↓ ↓H␈↓␈↓↓66 Applications␈↓ 22.4␈↓
␈↓ ↓H␈↓match␈αlist.␈αNote␈αthat␈αwe␈α␈↓↓have␈↓␈αassumed␈αthat␈α␈↓αmlist␈↓␈αis␈αa␈αlist.␈α We␈αwill␈αrestrict␈αthe␈αmatch␈αalgorithm␈αto
␈↓ ↓H␈↓simple␈α∂matches␈α∂on␈α∂tree␈α∂structure.␈α∂ We␈α∂represent␈α∞␈↓αprefix␈↓␈α∂as␈α∂␈↓αfirst␈↓␈α∂and␈α∂␈↓αsuffix␈↓␈α∂and␈α∂␈↓αrest␈↓;␈α∂much␈α∞more
␈↓ ↓H␈↓general␈α⊂interpretations␈α∂are␈α⊂possible.␈α∂ We␈α⊂leave␈α⊂it␈α∂to␈α⊂the␈α∂reader␈α⊂to␈α∂supply␈α⊂representations␈α⊂of␈α∂the
␈↓ ↓H␈↓missing functions.
␈↓ ↓H␈↓Given␈αa␈αbasic␈αpattern␈αmatcher,␈αwe␈αcan␈αbegin␈αto␈αelaborate␈αon␈αa␈αdata␈αbase␈αmanagement␈α
system.␈αWe
␈↓ ↓H␈↓need␈α∞some␈α∞means␈α∞of␈α∞controlling␈α∞the␈α∞matcher.␈α∞ If␈α∞several␈α∞entries␈α∞in␈α∞the␈α∞system␈α∞match␈α∞the␈α
inquiry,
␈↓ ↓H␈↓then␈α
we␈α
must␈α
decide␈α
how␈α
to␈α
manage␈α
the␈α
matches.␈α
In␈α
simple␈α
cases␈α
we␈α
could␈α
make␈α
a␈α
list␈α
of␈α
all␈αthe
␈↓ ↓H␈↓possibilities.␈α∂ If␈α∂the␈α∂number␈α∂of␈α∂matches␈α∂is␈α∂very␈α∂large␈α∞we␈α∂might␈α∂want␈α∂to␈α∂return␈α∂a␈α∂few␈α∂at␈α∂a␈α∞time,
␈↓ ↓H␈↓remembering␈α∞where␈α∞we␈α
were␈α∞in␈α∞the␈α
search␈α∞of␈α∞the␈α∞base.␈α
The␈α∞natural␈α∞extension␈α
of␈α∞this␈α∞idea␈α∞is␈α
to
␈↓ ↓H␈↓allow␈αa␈αpotentially␈αinfinite␈αset␈αof␈αelements␈αpresent␈αin␈αthe␈αdata␈αbase.␈αIn␈αprogramming␈αlanguages␈αwe
␈↓ ↓H␈↓are able to talk about such potentialities by using a procedure.
␈↓ ↓H␈↓Instead␈α
of␈α
having␈α
objects␈α
explicitly␈α
stored␈α
in␈α∞the␈α
base,␈α
we␈α
may␈α
allow␈α
procedures␈α
to␈α
occur␈α∞as␈α
data
␈↓ ↓H␈↓base␈α⊂elements.␈α⊂ Such␈α⊂a␈α⊂procedure␈α⊂would␈α⊂generate␈α⊂elements.␈α⊂For␈α⊂example,␈α⊂instead␈α⊂of␈α⊂storing␈α∂the
␈↓ ↓H␈↓integers␈αas␈αexplicit␈αobjects,␈αwe␈αcould␈αstore␈α
a␈αprocedure␈αto␈αgenerate␈αthe␈αintegers.␈αThis␈αintroduces␈α
two
␈↓ ↓H␈↓problems:␈α
how␈α
do␈α
we␈α
store␈α
procedures␈α
as␈α∞data␈α
objects;␈α
and,␈α
assuming␈α
that␈α
we␈α
have␈α
called␈α∞such␈α
a
␈↓ ↓H␈↓procedure␈α∞and␈α
it␈α∞has␈α∞delivered␈α
an␈α∞explicit␈α∞object,␈α
how␈α∞do␈α
we␈α∞represent␈α∞the␈α
notion␈α∞that␈α∞the␈α
␈↓↓next␈↓
␈↓ ↓H␈↓time␈α
we␈α
call␈α
that␈α
procedure,␈α
we␈α
want␈α
the␈α
␈↓↓next␈↓␈α
object?␈α
That␈α
is,␈α
a␈α
procedure␈α
named␈α
␈↓αget_next_integer␈↓
␈↓ ↓H␈↓should␈α
return␈α␈↓α1␈↓␈α
the␈αfirst␈α
time␈αit␈α
is␈αcalled,␈α
but␈αknow␈α
to␈α
return␈α␈↓α2␈↓␈α
the␈αnext␈α
time␈αit␈α
is␈αcalled␈α
in␈αthe␈α
same
␈↓ ↓H␈↓context. It must also know to return ␈↓α1␈↓ when it is called in a new context.
␈↓ ↓H␈↓Other␈αpossible␈αextensions␈αinvolve␈αthe␈αoperations␈αon␈α
the␈αbase.␈α Assume␈αthat␈αwe␈αknow␈αthat␈α"all␈α
roses
␈↓ ↓H␈↓are␈α∂red"␈α∞and␈α∂we␈α∞know␈α∂that␈α∞object␈α∂O␈↓β1␈↓␈α∞is␈α∂a␈α∞rose;␈α∂if␈α∞we␈α∂ask␈α∞the␈α∂data␈α∞base␈α∂for␈α∞all␈α∂red␈α∂objects,␈α∞we
␈↓ ↓H␈↓should␈αexpect␈αto␈αsee␈αO␈↓β1␈↓␈αappear␈αas␈αa␈αcandidate.␈αThat␈αexpectation␈αrequires␈αa␈αdeductive␈αability␈αbuilt
␈↓ ↓H␈↓into␈αthe␈αbase␈αmanipulator.␈αThat␈αis,␈αwe␈αneed␈αnot␈αhave␈αexplicitly␈αstored␈αthe␈αinformation␈αin␈αthe␈αbase,
␈↓ ↓H␈↓but␈α
we␈αexpect␈α
to␈αbe␈α
able␈αto␈α
deduce␈αfacts␈α
from␈αinformation␈α
in␈αthe␈α
base␈αusing␈α
some␈αrelationships␈α
and
␈↓ ↓H␈↓reasoning ability.
␈↓ ↓H␈↓There␈α
are␈α
at␈α
least␈α
two␈α
ways␈αthe␈α
"roses␈α
are␈α
red"␈α
problem␈α
can␈αbe␈α
solved.␈α
Notice␈α
that␈α
"all␈α
roses␈αare
␈↓ ↓H␈↓red"␈αis␈αmuch␈αlike␈αa␈αprocedure;␈αgiven␈αan␈αobject␈αwhich␈αis␈αa␈αrose,␈αit␈αgenerates␈αan␈αobject␈αwhich␈αis␈αred.
␈↓ ↓H␈↓So,␈αon␈αentering␈αa␈αrose␈αobject␈αin␈αthe␈αdata␈αbase,␈αthe␈αsystem␈αcould␈αalso␈αexplicitly␈αadd␈αthe␈αfact␈αthat␈αthe
␈↓ ↓H␈↓rose␈α⊂was␈α⊂red.␈α⊂This␈α⊂is␈α⊃an␈α⊂example␈α⊂of␈α⊂an␈α⊂␈↓↓input␈α⊂demon␈↓.␈α⊃A␈α⊂demon␈α⊂is␈α⊂a␈α⊂procedure␈α⊂which␈α⊃is␈α⊂not
␈↓ ↓H␈↓explicitly␈αcalled␈αbut␈αis␈αactivated␈αby␈αthe␈αoccurrence␈αof␈αanother␈αevent.␈α Whenever␈αan␈αobject␈αis␈αadded
␈↓ ↓H␈↓to␈α⊃the␈α⊃base␈α⊃the␈α⊃collection␈α⊃of␈α⊃input␈α⊃demons␈α⊂is␈α⊃checked.␈α⊃If␈α⊃an␈α⊃applicable␈α⊃demon␈α⊃is␈α⊃found,␈α⊃it␈α⊂is
␈↓ ↓H␈↓activated; its activation might activate other demons.
␈↓ ↓H␈↓The␈α∪activation␈α∩of␈α∪a␈α∪demon␈α∩is␈α∪a␈α∩different␈α∪kind␈α∪of␈α∩procedure␈α∪call␈α∩than␈α∪previously␈α∪seen.␈α∩The
␈↓ ↓H␈↓activation␈α
is␈α
done␈αon␈α
pattern␈α
matching␈α
rather␈αthan␈α
by␈α
a␈α
user-initiated␈αcall.␈α
Thus␈α
the␈α
calling␈αstyle␈α
is
␈↓ ↓H␈↓generally␈α⊂known␈α⊂as␈α⊂␈↓↓pattern␈α⊂directed␈α⊂invocation␈↓ ([Hew 72], [Bau 72]).␈α⊂ The␈α⊂demon␈α⊂procedure␈α⊂is
␈↓ ↓H␈↓stored␈αin␈αthe␈αdata␈αbase␈αalong␈αwith␈αa␈αpattern␈αwhich␈αdetermines␈αconditions␈αfor␈αits␈αactivation.␈αIn␈αthe
␈↓ ↓H␈↓case␈αof␈αan␈αinput␈αdemon,␈αan␈αinput␈αto␈αthe␈α
base␈αinitiates␈αa␈αmatch␈αof␈αthe␈αinput␈αdemon␈αpatterns␈α
against
␈↓ ↓H␈↓the␈αinput.␈αIf␈αa␈αmatch␈αis␈αfound,␈αthe␈αcorresponding␈αprocedure(s)␈αis(are)␈αexecuted.␈α The␈αmatch␈αprocess
␈↓ ↓H␈↓can␈α⊂bind␈α⊂variables␈α⊂to␈α⊂parts␈α∂of␈α⊂patterns␈α⊂and␈α⊂therefore␈α⊂the␈α∂procedure␈α⊂typically␈α⊂has␈α⊂access␈α⊂to␈α∂the
␈↓ ↓H␈↓match information.
␈↓ ↓H␈↓␈↓↓2.4␈↓ wData Bases 67␈↓
␈↓ ↓H␈↓Let's␈α
establish␈α
some␈α
notation␈α
and␈α
give␈α
an␈α
example.␈α
To␈α
introduce␈α
records␈α
to␈α
our␈α
system␈α
we␈α
use␈α
a
␈↓ ↓H␈↓unary procedure named ␈↓αadd_item␈↓. The argument to ␈↓αadd_item␈↓ is the record we wish to add.
␈↓ ↓H␈↓␈↓ ¬B␈↓αadd_item[(ROSE O1)]␈↓
␈↓ ↓H␈↓We␈α∩will␈α∪use␈α∩a␈α∩ternary␈α∪procedure␈α∩named␈α∩␈↓αadd_demon␈↓␈α∪to␈α∩insert␈α∩demons␈α∪in␈α∩the␈α∩base.␈α∪The␈α∩first
␈↓ ↓H␈↓argument␈αis␈αthe␈αtype␈αof␈αdemon;␈αso␈α
far␈αwe␈αhave␈αdiscussed␈αdemons␈αinvoked␈αby␈αadding␈α
elements;␈αwe
␈↓ ↓H␈↓will␈α∂also␈α∂have␈α∂demons␈α∂which␈α∂are␈α∂applied␈α∞when␈α∂items␈α∂are␈α∂removed,␈α∂or␈α∂when␈α∂items␈α∂are␈α∞accessed.
␈↓ ↓H␈↓These␈α⊂three␈α⊂types␈α∂will␈α⊂be␈α⊂named␈α⊂␈↓αADD␈↓,␈α∂␈↓αREMOVE␈↓,␈α⊂and␈α⊂␈↓αFETCH␈↓.␈α∂ The␈α⊂second␈α⊂argument␈α⊂is␈α∂the
␈↓ ↓H␈↓pattern␈α∂which␈α∂will␈α∂invoke␈α∂this␈α∂demon;␈α∂and␈α∂the␈α⊂third␈α∂argument␈α∂is␈α∂the␈α∂action␈α∂to␈α∂be␈α∂taken␈α⊂if␈α∂the
␈↓ ↓H␈↓pattern matches. For example:
␈↓ ↓H␈↓␈↓ ∧
␈↓αadd_demon[ADD;(ROSE ␈↓εa␈↓α);add_item[(RED ␈↓εa␈↓α))]]␈↓
␈↓ ↓H␈↓Demons are also used to monitor the removal of information from the base.
␈↓ ↓H␈↓The␈α⊂third␈α⊂use␈α⊃of␈α⊂demons␈α⊂is␈α⊃involved␈α⊂with␈α⊂another␈α⊃possible␈α⊂solution␈α⊂to␈α⊃the␈α⊂"all␈α⊂roses␈α⊃are␈α⊂red"
␈↓ ↓H␈↓problem.␈α Instead␈αof␈αexplicitly␈αadding␈αthe␈α
fact␈αthat␈α␈↓αO1␈↓␈αis␈αa␈αred␈α
object␈αwe␈αmight␈αwait␈αuntil␈αa␈α
request
␈↓ ↓H␈↓for␈αred␈α
objects␈αoccurs.␈α
At␈αthat␈α
time␈αwe␈αcould␈α
use␈αthe␈α
"all␈αroses␈α
are␈αred"␈α
demon␈α␈↓↓backwards␈↓.␈α That␈α
is,
␈↓ ↓H␈↓we␈αcould␈αlook␈αfor␈αany␈αroses␈αin␈αthe␈αdata␈αbase;␈αthe␈αassertion␈αthat␈αand␈αrose␈αobject␈αis␈αalso␈αa␈αred␈αobject
␈↓ ↓H␈↓allows␈α⊂us␈α⊃to␈α⊂accept␈α⊃rose␈α⊂objects␈α⊃as␈α⊂solutions␈α⊃to␈α⊂our␈α⊃inquiry.␈α⊂ This␈α⊃feature␈α⊂introduces␈α⊃a␈α⊂certain
␈↓ ↓H␈↓deductive capability to our system. It also introduces some organizational problems.
␈↓ ↓H␈↓We␈α
have␈α
to␈α
recognize␈α
when␈α∞a␈α
procedure␈α
is␈α
capable␈α
of␈α∞producing␈α
objects␈α
of␈α
the␈α
desired␈α∞type.␈α
We
␈↓ ↓H␈↓therefore␈α↔index␈α↔these␈α↔data␈α⊗base␈α↔procedures␈α↔by␈α↔a␈α⊗pattern␈α↔which␈α↔tells␈α↔what␈α↔the␈α⊗procedure
␈↓ ↓H␈↓accomplishes.␈αThat␈αpattern␈αis␈αcalled␈αthe␈αprocedure's␈αgoal␈αand␈αthe␈αinvocation␈αof␈αsuch␈αa␈αprocedure␈αis
␈↓ ↓H␈↓again pattern-directed, but has an added connotation of being ␈↓↓goal-oriented␈↓.
␈↓ ↓H␈↓Again,␈αwe␈αintroduce␈αsome␈αnotation␈αand␈αan␈αexample.␈αLet␈αthe␈αrequest␈αfor␈αa␈αdata␈αbase␈αitem␈αbe␈αgiven
␈↓ ↓H␈↓by:
␈↓ ↓H␈↓α␈↓ ¬⊂fetch[␈↓εa␈↓α]␈↓, where ␈↓εa␈↓ is a pattern.
␈↓ ↓H␈↓Since␈α∀a␈α∪␈↓αfetch␈↓␈α∀request␈α∪might␈α∀discover␈α∪several␈α∀possibilities,␈α∪some␈α∀being␈α∪items␈α∀and␈α∀some␈α∪being
␈↓ ↓H␈↓goal-directed procedures, we need a way of examining the selected information.
␈↓ ↓H␈↓We␈αintroduce␈αa␈αfunction␈αnamed␈α␈↓αtry_next␈↓,␈αwhose␈αsingle␈αargument␈αis␈αthe␈αresult␈αof␈αa␈α␈↓αfetch␈↓.␈α
Each␈αcall
␈↓ ↓H␈↓on ␈↓αtry_next␈↓ either produces a new item or signals that no more items exist on the fetch list.
␈↓ ↓H␈↓An␈α⊃extension␈α⊃to␈α⊃this␈α⊃basic␈α⊃data␈α⊃base␈α⊃manipulating␈α⊃system␈α⊃has␈α⊃become␈α⊃convenient␈α⊃in␈α⊃artificial
␈↓ ↓H␈↓intelligence␈α∞research.␈α∞Let␈α∞us␈α∞assume␈α∞we␈α∞wish␈α∞to␈α
derive␈α∞a␈α∞plan␈α∞or␈α∞scheme␈α∞for␈α∞achieving␈α∞a␈α
desired
␈↓ ↓H␈↓goal.␈α⊂In␈α∂the␈α⊂derivation␈α⊂process␈α∂we␈α⊂will␈α⊂make␈α∂hypotheses␈α⊂and␈α⊂then␈α∂pursue␈α⊂their␈α⊂implications.␈α∂A
␈↓ ↓H␈↓similar␈α⊃behavior␈α⊃can␈α⊂be␈α⊃simulated␈α⊃if␈α⊃we␈α⊂allow␈α⊃the␈α⊃creation␈α⊃of␈α⊂multiple␈α⊃data␈α⊃bases.␈α⊃Each␈α⊂base
␈↓ ↓H␈↓corresponds␈α∪to␈α∪a␈α∪hypothetical␈α∪situation␈α∪or␈α∪world,␈α∩and␈α∪the␈α∪␈↓αfetch␈↓-ing␈α∪of␈α∪an␈α∪object␈α∪in␈α∪a␈α∩world
␈↓ ↓H␈↓corresponds to asking whether or not a desired state is attainable in that world.
␈↓ ↓H␈↓␈↓↓68 Applications␈↓ 22.4␈↓
␈↓ ↓H␈↓Instead␈α⊂of␈α⊂requiring␈α∂that␈α⊂all␈α⊂transformations␈α∂occur␈α⊂in␈α⊂one␈α∂data␈α⊂base,␈α⊂several␈α⊂systems␈α∂([Con 73],
␈↓ ↓H␈↓[QA4 72])␈αhave␈αimplemented␈αa␈αlayered␈αdata␈αbase.␈α In␈αthis␈αsituation␈αwe␈αare␈αable␈αto␈αadd,␈αdelete␈αand
␈↓ ↓H␈↓fetch␈αfrom␈αspecified␈αdata␈αbases.␈αWe␈αadd␈αtwo␈αoperations␈α␈↓αpush_base␈↓␈αand␈α␈↓αpop_base␈↓␈αwhich␈αallow␈αus␈αto
␈↓ ↓H␈↓manipulate whole data bases as objects.
␈↓ ↓H␈↓The␈αcontrol␈αstructures␈αnecessary␈αfor␈αhandling␈αsuch␈αdata␈αbase␈αmanipulations␈αare␈αnon-recursive␈αand
␈↓ ↓H␈↓will␈α≤be␈α≤discussed␈α≤in␈α≤Section 4.5.␈α≤ We␈α≤will␈α≤discuss␈α≤some␈α≤details␈α≤of␈α≤the␈α≥data␈α≤structure
␈↓ ↓H␈↓implementation in Section 5.6. For more information see [McD 75] and [Con 73].
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I.␈α
Recall␈α
our␈α
discussion␈α
of␈α
␈↓αmatch␈↓␈α
on␈α∞page 65.␈α
Supply␈α
a␈α
representation␈α
for␈α
match␈α
lists␈α∞and␈α
supply
␈↓ ↓H␈↓the eight data structure functions.
␈↓ ↓H␈↓II.␈α
The␈α
␈↓αmatch␈↓␈α∞routine␈α
we␈α
developed␈α
on␈α∞page 65␈α
required␈α
that␈α
␈↓αpat␈↓␈α∞be␈α
a␈α
constant␈α
pattern.␈α∞Write␈α
a
␈↓ ↓H␈↓more␈α∞general␈α∞pattern␈α∞matcher␈α∞named␈α∞␈↓↓unify␈↓␈α∞which␈α∞allows␈α∞either␈α∞␈↓αpat␈↓␈α∞or␈α∞␈↓αexp␈↓␈α∞to␈α∞contain␈α∞variables.
␈↓ ↓H␈↓This more gereral match routine is called a unifier ([Rob 65]).
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓α␈↓ βrunify[(A (B ␈↓εa␈↓α) A); (A (␈↓εb␈↓α D) ␈↓εd␈↓α)] = ((␈↓εa␈↓α D)(␈↓εb␈↓α B) (␈↓εd␈↓α A))
␈↓ ↓H␈↓α␈↓ ∧Wunify[(A (B ␈↓εa␈↓α) A); (A (␈↓εb␈↓α D) ␈↓εb␈↓α)] = NO
␈↓ ↓H␈↓α␈↓ ¬λunify[(␈↓εa␈↓α A ␈↓εa␈↓α); (␈↓εb␈↓α ␈↓εb␈↓α B)] = NO
␈↓ ↓H␈↓␈↓ ¬∪␈↓↓2.5 Algebra of Polynomials␈↓
␈↓ ↓H␈↓Assume␈αthat␈αwe␈αwant␈αto␈αperform␈αaddition␈αand␈αmultiplication␈αof␈αpolynomials␈αand␈αassume␈αthat␈αeach
␈↓ ↓H␈↓polynomial␈α∞is␈α∂of␈α∞the␈α∂form␈α∞␈↓αp␈↓β1␈↓α␈α∂+␈α∞p␈↓β2␈↓α␈α∂+␈α∞...␈α∂+␈α∞p␈↓βn␈↓␈α∂where␈α∞each␈α∂term,␈α∞␈↓αp␈↓βi␈↓,␈α∂is␈α∞a␈α∂product␈α∞of␈α∂variables␈α∞and
␈↓ ↓H␈↓constants.␈α∂ The␈α∂two␈α∞components␈α∂of␈α∂each␈α∂term␈α∞are␈α∂a␈α∂constant␈α∂part␈α∞called␈α∂the␈α∂coefficient,␈α∂and␈α∞the
␈↓ ↓H␈↓variable␈αpart.␈α We␈αshall␈α
assume␈αwithout␈αloss␈αof␈α
generality␈αthat␈αthe␈αset␈α
of␈αvariables␈αwhich␈αappear␈α
in
␈↓ ↓H␈↓the␈α∂polynomials␈α∂are␈α∂lexicographically␈α∂ordered,␈α∂e.g. ␈↓αx < y < z␈↓;␈α∂and␈α∂assume␈α∂that␈α∂each␈α⊂variable␈α∂part
␈↓ ↓H␈↓obeys␈α∞that␈α
ordering;␈α∞thus␈α∞we␈α
would␈α∞insist␈α∞that␈α
␈↓αxzy␈↓π2␈↓␈α∞be␈α∞written␈α
␈↓αxy␈↓π2␈↓αz␈↓.␈α∞ We␈α∞do␈α
not␈α∞assume␈α∞that␈α
the
␈↓ ↓H␈↓terms␈α
are␈α
ordered␈α
within␈αthe␈α
polynomial;␈α
thus␈α
␈↓αx + xy␈↓␈α
and␈α␈↓αxy + x␈↓␈α
are␈α
both␈α
acceptable.␈α
We␈αfurther
␈↓ ↓H␈↓assume␈α⊂that␈α⊂the␈α⊂variables␈α⊂of␈α⊂each␈α∂␈↓αp␈↓βi␈↓␈α⊂are␈α⊂distinct␈α⊂and␈α⊂that␈α⊂no␈α∂␈↓αp␈↓βi␈↓␈α⊂has␈α⊂␈↓α0␈↓␈α⊂as␈α⊂its␈α⊂coefficient.␈α∂ The
␈↓ ↓H␈↓standard␈αalgorithm␈αfor␈αthe␈αaddition␈αof␈α␈↓λS␈↓πn␈↓βi=1␈↓αp␈↓βi␈↓␈αwith␈α␈↓λS␈↓πm␈↓βj=1␈↓αq␈↓βj␈↓␈αindicates␈αthat␈α␈↓αq␈↓βj␈↓␈αcan␈αbe␈αcombined␈αwith␈αa
␈↓ ↓H␈↓␈↓αp␈↓βi␈↓␈α
if␈α
the␈α
variable␈α
parts␈α∞of␈α
these␈α
terms␈α
are␈α
identical.␈α
In␈α∞this␈α
case␈α
the␈α
resulting␈α
term␈α
has␈α∞the␈α
same
␈↓ ↓H␈↓variable␈α⊂part␈α⊂but␈α⊂has␈α⊂a␈α⊂coefficient␈α⊂equal␈α⊂to␈α⊂the␈α⊂sum␈α⊂of␈α⊂the␈α⊂coefficients␈α⊂of␈α⊂␈↓αp␈↓βi␈↓␈α⊂and␈α⊂␈↓αq␈↓βj␈↓.␈α⊂ We␈α∂will
␈↓ ↓H␈↓examine␈α
four␈α
representations␈α
of␈α
polynomials,␈α
before␈αfinally␈α
writing␈α
any␈α
algorithms.␈α
To␈α
aid␈α
in␈αthe
␈↓ ↓H␈↓discussion we will use the polynomial ␈↓αx␈↓π2␈↓α - 2y - z␈↓ as our canonical example.
␈↓ ↓H␈↓␈↓↓2.5␈↓ λGAlgebra of Polynomials 69␈↓
␈↓ ↓H␈↓␈↓ ¬H␈↓↓First representation:␈↓
␈↓ ↓H␈↓We␈αcould␈αuse␈αthe␈αrepresentation␈αof␈αthe␈αdifferentiation␈αexample.␈α This␈αwould␈αresult␈αin␈αour␈αexample
␈↓ ↓H␈↓assuming the form:
␈↓ ↓H␈↓α␈↓ αo(PLUS (TIMES 1 (EXPT X 2)) (PLUS (TIMES -2 Y) (TIMES -1 Z))) .
␈↓ ↓H␈↓The␈α
above␈αconventions␈α
specify␈α
an␈αunambiguous␈α
representation␈α
for␈αour␈α
class␈α
of␈αpolynomials.␈α
Strictly
␈↓ ↓H␈↓speaking␈α∂we␈α∞did␈α∂not␈α∞need␈α∂to␈α∂impose␈α∞the␈α∂ordering␈α∞on␈α∂the␈α∂set␈α∞of␈α∂variables.␈α∞However,␈α∂we␈α∂need␈α∞to
␈↓ ↓H␈↓impose␈α
some␈αadditional␈α
constraints␈α
before␈αwe␈α
have␈α
data␈αstructures␈α
which␈α
are␈αwell-suited␈α
to␈αthe␈α
class
␈↓ ↓H␈↓of polynomial algorithms we wish to represent.
␈↓ ↓H␈↓␈↓ ¬9␈↓↓Second representation:␈↓
␈↓ ↓H␈↓We␈α∀are␈α∀really␈α∀only␈α∀interested␈α∀in␈α∀testing␈α∀the␈α∀equality␈α∀of␈α∀the␈α∀variable␈α∀parts;␈α∀we␈α∀will␈α∃not␈α∀be
␈↓ ↓H␈↓manipulating␈αvariable␈α
parts␈αin␈α
any␈αother␈α
way.␈α So␈α
we␈αmight␈α
simply␈αrepresent␈α
the␈αvariable␈α
part␈αas␈α
a
␈↓ ↓H␈↓list␈α∂of␈α∂pairs;␈α∂each␈α∂pair␈α∂contains␈α∂a␈α∂variable␈α∂name␈α∂and␈α∂the␈α∂corresponding␈α∂value␈α∂of␈α⊂the␈α∂exponent.
␈↓ ↓H␈↓Using␈α∀our␈α∀knowledge␈α∀of␈α∀the␈α∀forms␈α∀of␈α∪polynomials␈α∀and␈α∀the␈α∀class␈α∀of␈α∀algorithms␈α∀we␈α∀wish␈α∪to
␈↓ ↓H␈↓implement, we write ␈↓λS ␈↓αp␈↓βi␈↓ as:
␈↓ ↓H␈↓␈↓ ¬~␈↓α( (␈↓rep of ␈↓αp␈↓β1␈↓α), (␈↓rep of ␈↓αp␈↓β2␈↓α), ...)␈↓
␈↓ ↓H␈↓which would make our example look like:
␈↓ ↓H␈↓α␈↓ β#((TIMES 1 ((X . 2))), (TIMES -2 ((Y . 1))), (TIMES -1 ((Z . 1))))
␈↓ ↓H␈↓This␈αrepresentation␈αis␈αsufficient␈αand␈αit␈αdoes␈αhave␈αthe␈αflexibility␈αwe␈αneed,␈αbut␈αit␈αis␈αstill␈αnot␈αterribly
␈↓ ↓H␈↓satisfying. We are ignoring too much of the structure in our class of polynomials.
␈↓ ↓H␈↓␈↓ ¬A␈↓↓Third representation:␈↓
␈↓ ↓H␈↓We␈αknow␈αthat␈αthe␈αoccurrence␈αof␈αvariables␈αis␈αordered␈αin␈αeach␈αvariable␈αpart;␈αwe␈αcan␈αassume␈αthat␈αwe
␈↓ ↓H␈↓know the class of variables which may appear in any polynomial. So instead of writing ␈↓αx␈↓π2␈↓αy␈↓π3␈↓αz␈↓ as
␈↓ ↓H␈↓␈↓ ∧T␈↓α((X . 2) (Y . 3) (Z . 1))␈↓, we could write:
␈↓ ↓H␈↓␈↓ ∧≠␈↓α(2 3 1)␈↓ assuming ␈↓αx, y, z␈↓ are the only variables.
␈↓ ↓H␈↓In␈αa␈αfurther␈αsimplification,␈αnotice␈αthat␈αthe␈α␈↓αTIMES␈↓␈αin␈αthe␈αrepresentation␈αis␈αsuperfluous.␈αWe␈α␈↓↓always␈↓
␈↓ ↓H␈↓multiply␈α∂the␈α∂coefficient␈α∂by␈α∂the␈α∞variable␈α∂part.␈α∂So␈α∂we␈α∂could␈α∞simply␈α∂␈↓αconcat␈↓␈α∂the␈α∂coefficient␈α∂onto␈α∞the
␈↓ ↓H␈↓front of the variable part representation.
␈↓ ↓H␈↓␈↓↓70 Applications␈↓ 42.5␈↓
␈↓ ↓H␈↓Let's stop for some examples.
␈↓ ↓H␈↓␈↓ ¬_␈↓↓term␈↓ πλrepresentation
␈↓ ↓H␈↓↓␈↓ ¬_␈↓α2xyz␈↓ πλ(2 1 1 1)
␈↓ ↓H␈↓α␈↓ ¬_2x␈↓π2␈↓αz␈↓ πλ(2 2 0 1)
␈↓ ↓H␈↓α␈↓ ¬_4z␈↓π3␈↓α␈↓ πλ(4 0 0 3)
␈↓ ↓H␈↓Thus our canonical polynomial would now be represented as:
␈↓ ↓H␈↓α␈↓ ¬λ((1 2 0 0) (-2 0 1 0) (-1 0 0 1))
␈↓ ↓H␈↓This␈αrepresentation␈αis␈αnot␈αtoo␈αbad;␈αthe␈α␈↓αfirst␈↓-part␈α
of␈αany␈αterm␈αis␈αthe␈αcoefficient;␈αthe␈α␈↓αrest␈↓-part␈α
is␈αthe
␈↓ ↓H␈↓variable part. For example, the test for equality of variable parts is now simply a call on ␈↓αequal␈↓.
␈↓ ↓H␈↓Let's start thinking about the structure of the main algorithm.
␈↓ ↓H␈↓␈↓ ¬;␈↓↓Fourth representation:␈↓
␈↓ ↓H␈↓The␈α∀algorithm␈α∪for␈α∀the␈α∀sum␈α∪must␈α∀compare␈α∀terms.␈α∪Finding␈α∀similar␈α∀terms,␈α∪it␈α∀will␈α∀generate␈α∪an
␈↓ ↓H␈↓appropriate␈α∂new␈α⊂term,␈α∂otherwise␈α⊂it␈α∂simply␈α⊂copies␈α∂the␈α∂terms.␈α⊂ When␈α∂we␈α⊂pick␈α∂a␈α⊂␈↓αp␈↓βi␈↓␈α∂from␈α⊂the␈α∂first
␈↓ ↓H␈↓polynomial␈αwe␈α
would␈αlike␈αto␈α
find␈αa␈α
corresponding␈α␈↓αq␈↓βj␈↓␈αwith␈α
the␈αminimum␈α
amount␈αof␈αsearching.␈α
This
␈↓ ↓H␈↓can␈α⊂be␈α∂accomplished␈α⊂if␈α∂we␈α⊂can␈α∂order␈α⊂the␈α⊂terms␈α∂in␈α⊂the␈α∂polynomials.␈α⊂A␈α∂natural␈α⊂ordering␈α⊂can␈α∂be
␈↓ ↓H␈↓induced␈α⊂on␈α⊂the␈α⊂terms␈α⊂by␈α⊂ordering␈α⊃the␈α⊂numerical␈α⊂representation␈α⊂of␈α⊂the␈α⊂exponents.␈α⊂ For␈α⊃sake␈α⊂of
␈↓ ↓H␈↓argument,␈αassume␈α
that␈αa␈αmaximum␈α
of␈αtwo␈αdigits␈α
will␈αbe␈αneeded␈α
to␈αexpress␈αthe␈α
exponent␈αof␈αany␈α
one
␈↓ ↓H␈↓variable.␈α⊃Thus␈α⊃the␈α⊃exponent␈α⊃of␈α⊃␈↓αx␈↓π2␈↓␈α⊃will␈α⊃be␈α⊃represented␈α⊃as␈α⊃␈↓α02␈↓,␈α⊃or␈α⊃the␈α⊃exponent␈α⊃of␈α⊃␈↓αz␈↓π10␈↓␈α⊃will␈α⊂be
␈↓ ↓H␈↓represented as ␈↓α10␈↓. Combining this with our ordered representation of variable parts, we arrive at:
␈↓ ↓H␈↓␈↓ ¬_␈↓↓term␈↓ πλrepresentation
␈↓ ↓H␈↓α␈↓ ¬_43x␈↓π2␈↓αy␈↓π3␈↓αz␈↓π4␈↓ πλ␈↓α(43, 020304)
␈↓ ↓H␈↓α␈↓ ¬_2x␈↓π2␈↓αz␈↓ πλ(2, 020001)
␈↓ ↓H␈↓α␈↓ ¬_4z␈↓π3␈↓α␈↓ πλ(4, 000003)
␈↓ ↓H␈↓Now␈α∂we␈α⊂can␈α∂order␈α∂on␈α⊂the␈α∂numeric␈α⊂representation␈α∂of␈α∂the␈α⊂variable␈α∂part␈α∂of␈α⊂the␈α∂term.␈α⊂ One␈α∂more
␈↓ ↓H␈↓change of representation, which will result in a simplification in storage requirements:
␈↓ ↓H␈↓␈↓ ¬∧represent ␈↓α ax␈↓πA␈↓αy␈↓πB␈↓αz␈↓πC␈↓ as ␈↓α(a . ABC).
␈↓ ↓H␈↓This gives our final representation:
␈↓ ↓H␈↓α␈↓ ¬∞((1 . 20000) (-2 . 100) (-1 . 1))
␈↓ ↓H␈↓Note that ␈↓α20000 > 100 > 1␈↓.
␈↓ ↓H␈↓Finally␈αwe␈αwill␈αwrite␈αthe␈αalgorithm.␈α We␈αwill␈αassume␈αthat␈αthe␈αpolynomials␈αare␈αinitially␈αordered␈αand
␈↓ ↓H␈↓␈↓↓2.5␈↓ λGAlgebra of Polynomials 71␈↓
␈↓ ↓H␈↓will␈α
write␈α
the␈α
algorithm␈α
so␈α
as␈α
to␈α
maintain␈αthat␈α
ordering.␈α
Each␈α
term␈α
is␈α
a␈α
dotted␈α
pair␈α
of␈αelements:␈α
the
␈↓ ↓H␈↓coefficient and a representation of the variable part.
␈↓ ↓H␈↓As␈α∞in␈α
the␈α∞previous␈α∞differentiation␈α
example,␈α∞we␈α∞should␈α
attempt␈α∞to␈α∞extract␈α
the␈α∞algorithm␈α∞from␈α
the
␈↓ ↓H␈↓representation.
␈↓ ↓H␈↓We shall define:
␈↓ ↓H␈↓␈↓ ∧P␈↓αcoef[x] <= car[x]␈↓ and ␈↓α expo[x] <= cdr[x].
␈↓ ↓H␈↓To test the ordering we will use the LISP predicate:
␈↓ ↓H␈↓␈↓ ∧A␈↓αgreaterp[x;y] ␈↓gives ␈↓
t␈↓ if ␈↓αx␈↓ is greater than ␈↓αy␈↓.
␈↓ ↓H␈↓In␈α
the␈α
construction␈α
of␈α
the␈α
`sum'␈α
polynomial␈α
we␈α
will␈α
generate␈α
new␈α
terms␈α
by␈α
combining␈αcoefficients.
␈↓ ↓H␈↓So a constructor named ␈↓αnode␈↓ is needed. In terms of the latest representation ␈↓αnode␈↓ is defined as:
␈↓ ↓H␈↓␈↓ ¬C␈↓αnode[x;y] <= cons[x;y].␈↓
␈↓ ↓H␈↓So here's a graphical representation of our favorite polynomial:
␈↓ ↓H␈↓␈↓ ε
␈↓αx␈↓π2␈↓α - 2y - z ␈↓
␈↓"␈↓ ↓H␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ /\ \
␈↓"␈↓ ↓H␈↓∂ / \ /\
␈↓"␈↓ ↓H␈↓∂ 1 20000 / \
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ /\ \
␈↓"␈↓ ↓H␈↓∂ / \ \
␈↓"␈↓ ↓H␈↓∂ -2 100 /\
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ / ␈↓αNIL␈↓∂
␈↓"␈↓ ↓H␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ -1 1
␈↓ ↓H␈↓␈↓↓72 Applications␈↓ 42.5␈↓
␈↓ ↓H␈↓Here's the algorithm:
␈↓ ↓H␈↓αpolyadd[p;q] <=␈↓ β8[null[p] → q;
␈↓ ↓H␈↓α␈↓ β8 null[q] → p;
␈↓ ↓H␈↓α␈↓ β8 greaterp[expo[first[p]];expo[first[q]]] → concat[␈↓ λ_first[p];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧H␈↓ ¬λ␈↓ πh␈↓ λ_polyadd[rest[p];q]];
␈↓ ↓H␈↓α␈↓ β8 lessp[expo[first[p]];expo[first[q]]] → concat[␈↓ πhfirst[q];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧H␈↓ ¬λ␈↓ πhpolyadd[p;rest[q]]];
␈↓ ↓H␈↓α␈↓ β8 zerop[plus[coef[first[p]];coef[first[q]]]] → polyadd[rest[p];rest[q]];
␈↓ ↓H␈↓α␈↓ β8 ␈↓
t␈↓α → concat[␈↓ ∧Hnode[␈↓ ¬λplus[coef[first[p]];coef[first[q]]];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧H␈↓ ¬λexpo[first[p]]];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧Hpolyadd[rest[p];rest[q]]]]
␈↓ ↓H␈↓α␈↓ ¬Rzerop[x] <= eq[x;0]
␈↓ ↓H␈↓Now for an explanation and example.
␈↓ ↓H␈↓␈↓αpolyadd␈↓ is of the form: ␈↓α[p␈↓β1␈↓α → e␈↓β1␈↓α; p␈↓β2␈↓α → e␈↓β2␈↓α; p␈↓β3␈↓α → e␈↓β3␈↓α; p␈↓β4␈↓α → e␈↓β4␈↓α; p␈↓β5␈↓α → e␈↓β5␈↓α; p␈↓β6␈↓α → e␈↓β6␈↓α]
␈↓ ↓H␈↓␈↓αp␈↓β1␈↓α → e␈↓β1␈↓ and ␈↓αp␈↓β2␈↓α → e␈↓β2␈↓ check if either polynomial is empty.
␈↓ ↓H␈↓␈↓αp␈↓β3␈↓α␈α⊃→␈α⊃e␈↓β3␈↓␈α⊃and␈α⊃␈↓αp␈↓β4␈↓α␈α⊃→␈α⊃e␈↓β4␈↓.␈α⊃These␈α⊃clauses␈α⊃worry␈α⊃about␈α⊃the␈α⊃ordering␈α⊃of␈α⊃terms␈α⊃so␈α⊃that␈α⊃the␈α⊃resultant
␈↓ ↓H␈↓␈↓ αhpolynomial retains the ordering.
␈↓ ↓H␈↓Otherwise the variable parts are equal.
␈↓ ↓H␈↓␈↓αp␈↓β5␈↓α␈α→␈αe␈↓β5␈↓.␈α If␈αthe␈αvariable␈αparts␈αare␈αequal␈αthen␈αwe␈αcan␈αcombine␈αterms.␈α However,␈αwe␈αmust␈αcheck␈αfor
␈↓ ↓H␈↓␈↓ αhcancellations␈α↔and␈α↔not␈α↔include␈α↔any␈α_terms␈α↔with␈α↔zero␈α↔coefficient␈α↔in␈α_our␈α↔resultant
␈↓ ↓H␈↓␈↓ αhpolynomial.
␈↓ ↓H␈↓␈↓αp␈↓β6␈↓ → ␈↓αp␈↓β6␈↓. In the final case we must add a new node to our polynomial.
␈↓ ↓H␈↓Here's an informal execution of ␈↓αpolyadd:
␈↓ ↓H␈↓αpolyadd[x+y+z;x␈↓π2␈↓α-2y-z]
␈↓ ↓H␈↓α␈↓ αX= concat[x␈↓π2␈↓α;polyadd[x+y+z;-2y-z]]
␈↓ ↓H␈↓α␈↓ αX= concat[x␈↓π2␈↓α;concat[x;polyadd[y+z;-2y-z]]]
␈↓ ↓H␈↓α␈↓ αX= concat[x␈↓π2␈↓α;concat[x;concat[node[1+-2;y];polyadd[z;-z]]]]
␈↓ ↓H␈↓α␈↓ αX= concat[x␈↓π2␈↓α;concat[x;concat[-y;polyadd[z;-z]]]]
␈↓ ↓H␈↓α␈↓ αX= concat[x␈↓π2␈↓α;concat[x;concat[-y;polyadd[( );( )]]]]
␈↓ ↓H␈↓α␈↓ αX= concat[x␈↓π2␈↓α;concat[x;concat[-y;( )]]]
␈↓ ↓H␈↓α␈↓ ε≠= x␈↓π2␈↓α+x-y
␈↓ ↓H␈↓␈↓↓2.5␈↓ λGAlgebra of Polynomials 73␈↓
␈↓ ↓H␈↓Extensive␈α
work␈α
has␈α
been␈α
done␈α
on␈α
polynomial␈α
manipulating␈α
algorithms␈α
for␈α
efficient␈α
storage␈αand␈α
fast
␈↓ ↓H␈↓execution ([Got 76]).
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓ Write an algorithm, ␈↓αpolymult␈↓, to perform the multiplication of two polynomials.
␈↓ ↓H␈↓␈↓ ¬␈↓↓2.6 Evaluation of Polynomials␈↓
␈↓ ↓H␈↓Though␈α⊂you␈α⊂are␈α⊂undoubtedly␈α⊂quite␈α⊂tired␈α⊂of␈α⊂looking␈α⊂at␈α⊂polynomials,␈α⊂there␈α⊂is␈α⊂at␈α⊂least␈α⊂one␈α⊂more
␈↓ ↓H␈↓operation␈α∂which␈α∂is␈α⊂usefully␈α∂performed␈α∂on␈α∂polynomials.␈α⊂ The␈α∂operation␈α∂is␈α∂evaluation.␈α⊂ Given␈α∂an
␈↓ ↓H␈↓arbitrary␈α⊂polynomial,␈α⊃and␈α⊂values␈α⊃for␈α⊂any␈α⊃of␈α⊂the␈α⊃variables␈α⊂which␈α⊃it␈α⊂contains,␈α⊃we␈α⊂would␈α⊃like␈α⊂to
␈↓ ↓H␈↓compute␈α
its␈α∞value.␈α
First␈α∞we␈α
will␈α∞assume␈α
that␈α∞the␈α
substitutions␈α∞of␈α
values␈α∞for␈α
variables␈α∞has␈α
already
␈↓ ↓H␈↓been␈αcarried␈αout.␈αThus␈αwe␈αare␈αdealing␈αwith␈αpolynomials␈αof␈αthe␈αform:␈α␈↓λS␈↓πn␈↓βi=1␈↓αp␈↓βi␈↓␈αwhere␈α␈↓αp␈↓βi␈↓␈αis␈αa␈αproduct
␈↓ ↓H␈↓of powers of constants. For example:
␈↓ ↓H␈↓␈↓ ¬v␈↓α2␈↓π3␈↓α + 3*4␈↓π2␈↓α + 5␈↓.
␈↓ ↓H␈↓This could be represented as:
␈↓ ↓H␈↓␈↓ βU␈↓α(PLUS (EXPT 2 3) (PLUS (TIMES 3 (EXPT 4 2)) 5)).␈↓
␈↓ ↓H␈↓We␈αhave␈αtaken␈αthis␈α
general␈αrepresentation␈αbecause␈αwe␈α
have␈αgreat␈αexpectations␈αof␈α
generalizing␈αthe
␈↓ ↓H␈↓resulting algorithm.
␈↓ ↓H␈↓We␈α
will␈α
now␈α
describe␈α
a␈α
LISP␈α
function,␈α∞␈↓αvalue␈↓,␈α
which␈α
will␈α
take␈α
such␈α
an␈α
S-expr␈α∞representation␈α
and
␈↓ ↓H␈↓compute␈αits␈αvalue.␈α
Input␈αto␈α␈↓αvalue␈↓␈α
will␈αbe␈αnumerals␈α
or␈αlists␈αbeginning␈α
with␈αeither␈α␈↓αPLUS,␈αTIMES,␈↓␈α
or
␈↓ ↓H␈↓␈↓αEXPT␈↓.␈α
The␈αvalue␈α
of␈αa␈α
numeral␈αis␈α
that␈αnumeral;␈α
to␈αevaluate␈α
the␈αother␈α
forms␈αof␈α
input␈α
we␈αshould
␈↓ ↓H␈↓perform␈α⊗the␈α⊗operation␈α⊗represented.␈α⊗We␈α⊗must␈α⊗therefore␈α⊗assume␈α⊗that␈α⊗operations␈α⊗of␈α∃addition,
␈↓ ↓H␈↓multiplication,␈α∞and␈α∞exponentiation␈α∞exist.␈α∞ Assume␈α∞they␈α∞are␈α∞named␈α∞+,␈α∞*,␈α∞and␈α∞↑,␈α∂respectively.␈α∞What
␈↓ ↓H␈↓then␈αshould␈αbe␈α
the␈αvalue␈αof␈αa␈α
representation␈αof␈αa␈αsum?␈α
It␈αshould␈αbe␈αthe␈α
result␈αof␈αadding␈αthe␈α
value
␈↓ ↓H␈↓of␈αthe␈αrepresentations␈α
of␈αthe␈αtwo␈α
summands␈αor␈αoperands.␈α
That␈αis,␈α␈↓αvalue␈↓␈α
is␈αrecursive.␈α It␈αshould␈α
now
␈↓ ↓H␈↓be clear how to write ␈↓αvalue␈↓:
␈↓ ↓H␈↓αvalue[x] <=␈↓ αX[isconstant[x] → x;
␈↓ ↓H␈↓α␈↓ αX issum[x] → +[value[arg␈↓β1␈↓α[x]];value[arg␈↓β2␈↓α[x]]];
␈↓ ↓H␈↓α␈↓ αX isprod[x] → *[value[arg␈↓β1␈↓α[x]];value[arg␈↓β2␈↓α[x]]];
␈↓ ↓H␈↓α␈↓ αX isexpt[x] → ↑[value[arg␈↓β1␈↓α[x]];value[arg␈↓β2␈↓α[x]]]]
␈↓ ↓H␈↓␈↓↓74 Applications␈↓ 52.6␈↓
␈↓ ↓H␈↓where:
␈↓ ↓H␈↓α␈↓ ¬≥isconstant[x] <= numberp[x]
␈↓ ↓H␈↓α␈↓ ¬∂issum[x] <= eq[first[x];PLUS]
␈↓ ↓H␈↓α␈↓ ¬↓isprod[x] <= eq[first[x];TIMES]
␈↓ ↓H␈↓α␈↓ ¬
isexpt[x] <= eq[first[x];EXPT]
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓1. Show how to extend ␈↓α value␈↓ to handle binary and unary minus.
␈↓ ↓H␈↓2.␈α∪ Write␈α∩an␈α∪algorithm␈α∩␈↓αinstantiate␈↓␈α∪which␈α∪will␈α∩take␈α∪two␈α∩arguments,␈α∪one␈α∩representing␈α∪a␈α∪set␈α∩of
␈↓ ↓H␈↓variables␈α↔and␈α↔values,␈α↔the␈α↔other␈α↔representing␈α⊗a␈α↔polynomial.␈α↔The␈α↔algorithm␈α↔is␈α↔to␈α↔return␈α⊗a
␈↓ ↓H␈↓representation of the polynomial which would result from substituting the values for the variables.
␈↓ ↓H␈↓3.␈α⊂ It␈α⊂would␈α∂be␈α⊂nice␈α⊂if␈α∂we␈α⊂could␈α⊂represent␈α∂expressions␈α⊂like␈α⊂2+3+4␈α∂as␈α⊂␈↓α(PLUS 2 3 4)␈↓␈α⊂rather␈α∂than
␈↓ ↓H␈↓␈↓α(PLUS (PLUS 2 3) 4)␈↓␈α>or␈α>␈↓α(PLUS 2 (PLUS 3 4))␈↓;␈α>or␈α>represent␈α>2*3*4+5+6␈α>as
␈↓ ↓H␈↓␈↓α(PLUS (TIMES 2 3 4) 5 6)␈↓.
␈↓ ↓H␈↓Write a new version of ␈↓αvalue␈↓ which can evaluate such n-ary representations of + and *.
␈↓ ↓H␈↓␈↓ ∧⎇␈↓↓More on polynomial evaluation␈↓
␈↓ ↓H␈↓Though␈α
it␈αshould␈α
be␈α
clear␈αthat␈α
the␈α
current␈α␈↓αvalue␈↓␈α
function␈α
does␈αperform␈α
the␈αappropriate␈α
calculation,
␈↓ ↓H␈↓it␈α⊂should␈α⊂be␈α⊂equally␈α⊂clear␈α∂that␈α⊂the␈α⊂class␈α⊂of␈α⊂expressions␈α∂which␈α⊂␈↓αvalue␈↓␈α⊂handles␈α⊂is␈α⊂not␈α∂particularly
␈↓ ↓H␈↓powerful. We might wish to evaluate requests like:
␈↓ ↓H␈↓␈↓ A␈↓␈↓ β("What is the value of ␈↓αx*y + 2*z␈↓ when ␈↓αx=4, y=2,␈↓ and ␈↓αz=1␈↓?"
␈↓ ↓H␈↓Now␈αthe␈αfunction␈α␈↓αinstantiate␈↓,␈αrequested␈αin␈αproblem␈α2␈αabove,␈αoffers␈αone␈αsolution:␈αmake␈αa␈αnew␈αcopy
␈↓ ↓H␈↓of␈α∞the␈α∞representation␈α∞of␈α∞␈↓αx*y + 2*z␈↓␈α∞with␈α∞the␈α∞variables␈α∞physically␈α∞replaced␈α∞by␈α∞their␈α∞values␈↓π 48␈↓.␈α∞This
␈↓ ↓H␈↓would␈α∂result␈α∞in␈α∂a␈α∞representation␈α∂of␈α∞␈↓α4*2 +2*1␈↓,␈α∂and␈α∞this␈α∂new␈α∞expression␈α∂is␈α∞suitable␈α∂fare␈α∂for␈α∞␈↓αvalue␈↓.
␈↓ ↓H␈↓Computationally,␈α∪this␈α∪is␈α∪a␈α∀terrible␈α∪solution.␈α∪ ␈↓αinstantiate␈↓␈α∪will␈α∀go␈α∪through␈α∪the␈α∪structure␈α∀of␈α∪the
␈↓ ↓H␈↓expression␈α∀looking␈α∪for␈α∀instances␈α∀of␈α∪variables,␈α∀and␈α∪when␈α∀located,␈α∀will␈α∪replace␈α∀them␈α∀with␈α∪the
␈↓ ↓H␈↓appropriate␈α∞values.␈α∞␈↓αvalue␈↓␈α∞then␈α∞goes␈α∞through␈α∞the␈α∞structure␈α∞of␈α∞the␈α∞resulting␈α∞expression␈α
performing
␈↓ ↓H␈↓the␈αevaluation.␈αWe␈αdesire␈αa␈αfunction,␈α␈↓αvalue␈↓λ'␈↓,␈αwhich␈αcombines␈αthe␈αtwo␈αprocesses:␈αthe␈αbasic␈αstructure
␈↓ ↓H␈↓of␈α∞␈↓αvalue␈↓λ'␈↓␈α
is␈α∞that␈α
of␈α∞mild-mannered␈α
␈↓αvalue␈↓,␈α∞but␈α∞when␈α
a␈α∞variable,␈α
say␈α∞␈↓αx␈↓,␈α
is␈α∞recognized␈α∞inside␈α
␈↓αvalue␈↓λ'␈↓
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 48␈↓␈αWe␈α
have␈αseen␈αthis␈α
substitution␈αand␈αsimplification␈α
process␈αbefore␈αin␈α
discussing␈α␈↓αequal␈↓␈αon␈α
page 23.
␈↓ ↓H␈↓It is a minimal but useful model for computation.
␈↓ ↓H␈↓␈↓↓2.6␈↓ λ Evaluation of Polynomials 75␈↓
␈↓ ↓H␈↓then␈α∞␈↓αvalue␈↓λ'␈↓␈α∞would␈α∞look␈α∞at␈α∞a␈α∞table␈α∞like␈α∞that␈α∞expected␈α∞by␈α∞␈↓αinstantiate␈↓,␈α∞find␈α∞␈↓αx␈↓␈α∞and␈α∞return␈α∂the␈α∞value
␈↓ ↓H␈↓associated with the entry for ␈↓αx␈↓.
␈↓ ↓H␈↓Let's␈αformalize␈αour␈αintuitions␈αabout␈α
␈↓αvalue␈↓λ'␈↓.␈αIt␈αwill␈αbe␈αa␈αfunction␈α
of␈αtwo␈αarguments.␈αThe␈αfirst␈αwill␈α
be
␈↓ ↓H␈↓a␈αrepresentation␈αof␈αa␈αpolynomial;␈αthe␈αsecond␈αwill␈αbe␈αa␈αrepresentation␈αof␈αthe␈αtable␈αof␈αvariables␈αand
␈↓ ↓H␈↓values.␈αYou␈αmay␈α
have␈αnoticed␈αthat␈αthe␈α
original␈αversion␈αof␈α␈↓αvalue␈↓␈α
␈↓↓does␈↓␈αhandle␈αexpressions␈αwhich␈α
are
␈↓ ↓H␈↓not␈α
actually␈α
constant␈α
polynomials;␈α
␈↓α(2 + 3)*4␈↓␈α
for␈αexample.␈α
Since␈α
we␈α
will␈α
wish␈α
to␈α
apply␈αour␈α
evaluation
␈↓ ↓H␈↓functions␈αto␈αmore␈αgeneral␈αclasses␈αof␈αexpressions␈αwe␈αwill␈αcontinue,␈αindeed␈αencourage,␈αthis␈αgenerality.
␈↓ ↓H␈↓Regardless␈α∞of␈α∞the␈α∞class␈α∞of␈α∞expressions␈α∞we␈α∞wish␈α∞to␈α∞examine,␈α∞it␈α∞is␈α∞the␈α∞structure␈α∞of␈α∞the␈α∞table␈α
which
␈↓ ↓H␈↓should␈α∂be␈α⊂the␈α∂first␈α∂order␈α⊂of␈α∂business.␈α∂ An␈α⊂appropriate␈α∂table,␈α∂␈↓αtbl␈↓,␈α⊂will␈α∂be␈α∂a␈α⊂set␈α∂of␈α⊂ordered␈α∂pairs
␈↓ ↓H␈↓␈↓α<name␈↓βi␈↓α, val␈↓βi␈↓α>␈↓;␈αthus␈αfor␈αthe␈αabove␈αexample␈αthe␈αtable␈α␈↓α{<x, 4>, <y, 2>, <z, 1>}␈↓␈αwould␈αsuffice.␈α Following
␈↓ ↓H␈↓our␈α∞dictum␈α
of␈α∞abstraction␈α
and␈α∞representation-independent␈α
programming,␈α∞we␈α
will␈α∞not␈α∞worry␈α
about
␈↓ ↓H␈↓the␈α
representational␈α
problems␈α
of␈α
such␈α
tables.␈α
We␈α
will␈α
simply␈α
assume␈α
that␈α
"tables"␈α
are␈α
instances␈αof
␈↓ ↓H␈↓an␈αabstract␈αdata␈αstructure␈αcalled␈α␈↓<table>␈↓,␈αand␈αwe␈αwill␈αonly␈αconcern␈αourselves␈αfor␈αthe␈αmoment␈αwith
␈↓ ↓H␈↓the␈αkinds␈αof␈αoperations␈αwe␈αneed␈αto␈αperform.␈α
We␈αwill␈αneed␈αtwo␈αselector␈αfunctions:␈α␈↓αname␈↓,␈αto␈αselect␈α
the
␈↓ ↓H␈↓variable-component␈αof␈αa␈αtable␈αentry;␈αand␈α␈↓αval␈↓,␈αto␈αselect␈αthe␈αvalue-component.␈αA␈α
complete␈αdiscussion
␈↓ ↓H␈↓of␈αsuch␈αa␈αdata␈αstructure␈αwould␈αentail␈αdiscussion␈αof␈αconstructors␈αand␈αrecognizers,␈αand␈αperhaps␈αother
␈↓ ↓H␈↓functions, but for the current ␈↓αvalue␈↓λ'␈↓, these two functions will suffice.
␈↓ ↓H␈↓␈↓αvalue␈↓λ'␈↓␈α
will␈α
need␈αa␈α
table-function,␈α
␈↓αlocate␈↓,␈αto␈α
locate␈α
an␈αappropriate␈α
variable-value␈α
entry.␈α
The␈αbinary
␈↓ ↓H␈↓function␈α␈↓αlocate␈↓␈αwill␈αtake␈α
an␈αargument,␈α␈↓αx␈↓,␈αrepresenting␈αa␈α
variable;␈αand␈αan␈αargument,␈α␈↓αtbl␈↓,␈α
representing
␈↓ ↓H␈↓a␈αtable.␈α
␈↓αlocate␈↓␈αwill␈αmatch␈α
␈↓αx␈↓␈αagainst␈αthe␈α
␈↓αname␈↓-part␈αof␈α
each␈αelement␈αin␈α
␈↓αtbl␈↓;␈αif␈αa␈α
match␈αis␈α
found␈αthen
␈↓ ↓H␈↓the corresponding ␈↓αval␈↓-part is returned. If no match is found then ␈↓αlocate␈↓ is undefined.
␈↓ ↓H␈↓So␈α
far,␈αlittle␈α
structure␈α
has␈αbeen␈α
imposed␈α
on␈αelements␈α
of␈α
␈↓<table>␈↓;␈αtables␈α
are␈α
either␈αempty␈α
or␈αnot;␈α
but
␈↓ ↓H␈↓if␈αa␈αtable␈αis␈αnon-empty␈αthen␈αeach␈αelement␈αis␈αa␈αpair␈αwith␈αrecognizable␈αcomponents␈αof␈α␈↓αname␈↓␈αand␈α␈↓αval␈↓.
␈↓ ↓H␈↓However,␈α
the␈α
specification␈α
of␈α
algorithms␈α∞to␈α
examine␈α
elements␈α
of␈α
␈↓<table>␈↓␈α
imposes␈α∞more␈α
structure
␈↓ ↓H␈↓on␈αour␈αtables.␈α If␈αwe␈αwere␈αdealing␈αwith␈αmathematical␈αfunctions␈αrather␈αthan␈αalgorithms␈αthen␈αa␈αside
␈↓ ↓H␈↓condition␈α
to␈α
the␈α
effect␈α
that␈α
a␈α
table␈α
had␈α
no␈α
pairs␈α
with␈α
duplicate␈α
first␈α
elements␈α
would␈α
be␈α
sufficient
␈↓ ↓H␈↓(and␈α
required).␈α
However,␈α
we␈α
are␈α
dealing␈α
with␈α
algorithms␈α
and␈α
therefore␈α
must␈α
describe␈α
a␈αmethod␈α
for
␈↓ ↓H␈↓locating elements.
␈↓ ↓H␈↓Recursion␈αis␈αthe␈αonly␈αmethod␈αwe␈αhave␈α
for␈αspecifying␈α␈↓αlocate␈↓,␈αand␈αrecursion␈αoperates␈αby␈α
decomposing
␈↓ ↓H␈↓a␈αstructure.␈αSets␈αare␈αnotorious␈αfor␈αtheir␈αlack␈αof␈αstructure;␈αthere␈αis␈αno␈αorder␈αto␈αthe␈αelements␈αof␈αa␈αset.
␈↓ ↓H␈↓But␈αif␈αwe␈αare␈αto␈αwrite␈αa␈αLISP␈αalgorithm␈αfor␈α␈↓αlocate␈↓,␈αthat␈αalgorithm␈αwill␈αhave␈αto␈αbe␈αrecursive␈αon␈αthe
␈↓ ↓H␈↓"structure"␈α∂of␈α∞␈↓αtbl␈↓,␈α∂and␈α∂so␈α∞we␈α∂impose␈α∞an␈α∂ordering␈α∂on␈α∞the␈α∂elements␈α∞of␈α∂that␈α∂table.␈α∞That␈α∂is,␈α∂we␈α∞will
␈↓ ↓H␈↓represent tables as ␈↓↓sequences␈↓. We know how to represent sequences in LISP: we use lists.
␈↓ ↓H␈↓With this introduction, here's ␈↓αlocate␈↓␈↓π 49␈↓:
␈↓ ↓H␈↓αlocate[x;tbl] <=␈↓ β_[eq[name[first[tbl]];x] → val[first[tbl]];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → locate[x;rest[tbl]] ]
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 49␈↓␈α∞The␈α∞interpretation␈α
of␈α∞␈↓αtbl␈↓␈α∞as␈α∞a␈α
function␈α∞implies␈α∞that␈α
␈↓αlocate␈↓␈α∞represents␈α∞function␈α∞application;␈α
i.e.,
␈↓ ↓H␈↓␈↓αlocate[x;tbl] ␈↓is␈↓α tbl(x)␈↓.This is a very acceptable interpretation of table lookup.
␈↓ ↓H␈↓␈↓↓76 Applications␈↓ 52.6␈↓
␈↓ ↓H␈↓The␈αeffect␈αof␈α␈↓αlocate␈↓␈αis␈αto␈αfind␈αthe␈α␈↓↓first␈↓␈αelement␈αof␈α␈↓αtbl␈↓␈αwhich␈αhas␈αa␈α␈↓αname␈↓-component␈αwhich␈αmatches
␈↓ ↓H␈↓␈↓αx␈↓.␈α
Having␈α
found␈α
that␈α
match,␈α
the␈α
corresponding␈α
␈↓αval␈↓-part␈α
is␈α
returned.␈α
If␈α
there␈α
were␈α
other␈α
matches
␈↓ ↓H␈↓further␈α⊃along␈α⊃in␈α⊃the␈α⊃sequence␈α⊃␈↓αlocate␈↓␈α∩would␈α⊃not␈α⊃see␈α⊃them.␈α⊃ Other␈α⊃representations␈α⊃of␈α∩tables␈α⊃are
␈↓ ↓H␈↓certainly possible. This representation will be useful in later applications.
␈↓ ↓H␈↓And here's the new more powerful ␈↓αvalue␈↓λ'␈↓:
␈↓ ↓H␈↓αvalue␈↓λ'␈↓α[x;tbl] <=␈↓ β([isconstant[x] → x;
␈↓ ↓H␈↓α␈↓ β( isvar[x] → locate[x;tbl];
␈↓ ↓H␈↓α␈↓ β( issum[x] → +[␈↓ ∧hvalue␈↓λ'␈↓α[arg␈↓β1␈↓α[x];tbl];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧hvalue␈↓λ'␈↓α[arg␈↓β2␈↓α[x];tbl]];
␈↓ ↓H␈↓α␈↓ β( isprod[x] → *[␈↓ ∧hvalue␈↓λ'␈↓α[arg␈↓β1␈↓α[x];tbl];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧hvalue␈↓λ'␈↓α[arg␈↓β2␈↓α[x];tbl]];
␈↓ ↓H␈↓α␈↓ β( isexpt[x] → ↑[␈↓ ∧hvalue␈↓λ'␈↓α[arg␈↓β1␈↓α[x];tbl];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧hvalue␈↓λ'␈↓α[arg␈↓β2␈↓α[x];tbl]] ]
␈↓ ↓H␈↓Notice␈αthat␈α␈↓αtbl␈↓␈αis␈αcarried␈αthrough␈αas␈αan␈αexplicit␈αargument␈αto␈α␈↓αvalue␈↓λ'␈↓␈αeven␈αthough␈αit␈αis␈αonly␈αaccessed
␈↓ ↓H␈↓when␈αa␈αvariable␈αis␈αrecognized.␈α Notice␈αtoo␈αthat␈αmuch␈αof␈αthe␈αstructure␈αof␈α␈↓αvalue␈↓λ'␈↓␈αis␈αquite␈αrepetitious;
␈↓ ↓H␈↓the␈α∂lines␈α∂which␈α∞handle␈α∂sums,␈α∂products,␈α∞and␈α∂exponentiation␈α∂are␈α∞identical␈α∂except␈α∂for␈α∂the␈α∞function
␈↓ ↓H␈↓which␈α∂finally␈α∂gets␈α∂applied␈α∂to␈α∂the␈α∂evaluated␈α∂arguments.␈α∂ That␈α∂is,␈α∂the␈α∂basic␈α∂structure␈α∂of␈α∂␈↓αvalue␈↓λ'␈↓␈α∞is
␈↓ ↓H␈↓potentially␈α
of␈α
broader␈α
application␈α
than␈α
just␈α
the␈α
simple␈α
class␈α
of␈α
polynomials.␈α
In␈α
keeping␈α
with␈α
our
␈↓ ↓H␈↓search for generality, let's pursue ␈↓αvalue␈↓λ'␈↓ a little further.
␈↓ ↓H␈↓What ␈↓αvalue␈↓λ'␈↓ says is:
␈↓ ↓H␈↓␈↓↓1.␈↓ The value of a constant is that constant.
␈↓ ↓H␈↓␈↓↓2.␈↓ The value of a variable is the current value associated with that variable in the table.
␈↓ ↓H␈↓␈↓↓3.␈↓␈αThe␈αvalue␈αof␈αa␈αfunction␈αcall␈αis␈αthe␈αresult␈αof␈αapplying␈αthe␈αfunction␈αto␈αthe␈αevaluated␈αarguments.␈αIt
␈↓ ↓H␈↓just␈α∃turns␈α∀out␈α∃that␈α∃the␈α∀only␈α∃functions␈α∃␈↓αvalue␈↓λ'␈↓␈α∀knows␈α∃about␈α∃are␈α∀binary␈α∃sums,␈α∃products,␈α∀and
␈↓ ↓H␈↓exponentiation.
␈↓ ↓H␈↓Let's clean up ␈↓αvalue␈↓λ'␈↓ a bit.
␈↓ ↓H␈↓αvalue␈↓λ'␈↓α[x;tbl] <=␈↓ β_[isconstant[x] → x;
␈↓ ↓H␈↓α␈↓ β_ isvar[x] → locate[x;tbl];
␈↓ ↓H␈↓α␈↓ β_ isfun_args[x] → apply[␈↓ ¬Xfun[x];
␈↓ ↓H␈↓α␈↓ β_␈↓ ¬Xeval_args[args[x];tbl]
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → ␈↓λB␈↓α]
␈↓ ↓H␈↓The␈αchanges␈αare␈αin␈αthe␈αthird␈αbranch␈αof␈αthe␈αconditional.␈αWe␈αhave␈αa␈αnew␈αrecognizer,␈α␈↓αisfun_args␈↓␈αto
␈↓ ↓H␈↓recognize␈α
function␈α
application.␈α
We␈α
have␈α
two␈α
new␈α
selector␈α
functions;␈α
␈↓αfun␈↓␈α
selects␈α
the␈α
representation␈α
of
␈↓ ↓H␈↓the␈αfunction␈α-- sum,␈αproduct,␈αor␈αpower␈αin␈αthe␈αsimple␈αcase;␈α␈↓αargs␈↓␈αselects␈αthe␈αarguments␈αor␈αparameters
␈↓ ↓H␈↓to␈α⊂the␈α⊃function␈α⊂-- in␈α⊃this␈α⊂case␈α⊃all␈α⊂functions␈α⊂are␈α⊃binary.␈α⊂We␈α⊃have␈α⊂two␈α⊃new␈α⊂functions␈α⊃to␈α⊂define:
␈↓ ↓H␈↓␈↓↓2.6␈↓ λ Evaluation of Polynomials 77␈↓
␈↓ ↓H␈↓␈↓αeval_args␈↓,␈α
which␈α
is␈α
supposed␈α
to␈α
evaluate␈α
the␈α
arguments␈α
finding␈α
values␈α
for␈α
any␈α
of␈α
the␈α
variables;␈α
and
␈↓ ↓H␈↓␈↓αapply␈↓, which is used to perform the desired operation on the evaluated arguments.
␈↓ ↓H␈↓We␈α⊃are␈α⊃still␈α⊃trying␈α⊃to␈α⊃remain␈α⊃as␈α⊃representation-free␈α⊃as␈α⊃possible:␈α⊃thus␈α⊃the␈α⊃generalization␈α⊃of␈α⊂the
␈↓ ↓H␈↓algorithm␈α␈↓αvalue␈↓λ'␈↓,␈αand␈αthus␈αthe␈αcare␈αin␈αpicking␈αrepresentations␈αfor␈αthe␈αdata␈αstructures.␈α We␈αneed␈αto
␈↓ ↓H␈↓make␈α
another␈αdata␈α
structure␈αdecision␈α
now;␈α
when␈αwriting␈α
the␈αfunction␈α
␈↓αeval_args␈↓,␈α
we␈αwill␈α
be␈αgiving␈α
a
␈↓ ↓H␈↓recursive␈αalgorithm.␈α This␈αalgorithm␈αwill␈αbe␈αrecursive␈αon␈αthe␈αstructure␈αof␈αthe␈αfirst␈αargument,␈α
which
␈↓ ↓H␈↓is␈α
a␈α
representation␈α
of␈αthe␈α
arguments␈α
to␈α
the␈αfunction.␈α
In␈α
contrast␈α
to␈αour␈α
position␈α
when␈α
writing␈αthe
␈↓ ↓H␈↓function␈α
␈↓αlocate␈↓,␈αthere␈α
␈↓↓is␈↓␈αa␈α
natural␈αstructure␈α
on␈αthe␈α
arguments␈αto␈α
a␈αfunction:␈α
they␈αform␈α
a␈αsequence.
␈↓ ↓H␈↓That␈α⊂is␈α∂␈↓αf[1;2;3]␈↓␈α⊂is␈α⊂typically␈α∂not␈α⊂the␈α⊂same␈α∂as␈α⊂␈↓αf[3;2;1]␈↓␈α⊂or␈α∂␈↓αf␈↓␈α⊂applied␈α⊂to␈α∂any␈α⊂other␈α⊂permutation␈α∂of
␈↓ ↓H␈↓{1, 2, 3}.␈α⊃Thus␈α∩writing␈α⊃␈↓αeval_args␈↓␈α⊃as␈α∩a␈α⊃function,␈α∩recursive␈α⊃on␈α⊃the␈α∩sequence-structure␈α⊃of␈α∩its␈α⊃first
␈↓ ↓H␈↓argument, is quite natural. Here is ␈↓αeval_args␈↓:
␈↓ ↓H␈↓αeval_args[args;tbl] <=␈↓ βx[null[args] → ();
␈↓ ↓H␈↓α␈↓ βx ␈↓
t␈↓α → concat[␈↓ ¬_value␈↓λ'␈↓α[first[args];tbl];
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬_eval_args[rest[args];tbl]] ]
␈↓ ↓H␈↓Notice␈αthat␈αwe␈αhave␈αwritten␈α␈↓αeval_args␈↓␈αwithout␈αany␈αbias␈αtoward␈αbinary␈αfunctions;␈αit␈αwill␈αevaluate␈αa
␈↓ ↓H␈↓sequence of arbitrary length, returning a sequence representing the evaluated arguments.
␈↓ ↓H␈↓There␈αshould␈αbe␈αno␈αreal␈α
surprises␈αin␈α␈↓αapply␈↓;␈αit␈αgets␈αthe␈α
representation␈αof␈αthe␈αfunction␈αname␈αand␈α
the
␈↓ ↓H␈↓sequence of evaluated arguments and does its job:
␈↓ ↓H␈↓αapply[fn; evargs] <=␈↓ βx[issum[fn] → +[␈↓ ¬Harg␈↓β1␈↓α[evargs];
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬Harg␈↓β2␈↓α[evargs]];
␈↓ ↓H␈↓α␈↓ βx isprod[fn] → *[␈↓ ¬Harg␈↓β1␈↓α[evargs];
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬Harg␈↓β2␈↓α[evargs]];
␈↓ ↓H␈↓α␈↓ βx isexpt[fn] → ↑[␈↓ ¬Harg␈↓β1␈↓α[evargs];
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬Harg␈↓β2␈↓α[evargs]] ]
␈↓ ↓H␈↓If␈αwe␈αshould␈αdesire␈αto␈αrecognize␈αmore␈αfunctions␈αthen␈αwe␈αneed␈αonly␈αmodify␈α␈↓αapply␈↓.␈αThat␈αwould␈αbe␈αa
␈↓ ↓H␈↓satisfactory␈αshort-term␈αsolution,␈αbut␈αwe␈αwould␈αlike␈αa␈αmore␈αgeneral␈αfunction-definition␈αfacility.␈αSuch
␈↓ ↓H␈↓a␈αfeature␈αwould␈αallow␈αnew␈αfunctions␈αto␈αbe␈αdefined␈αduring␈αa␈αcomputation;␈αthen␈αif␈αan␈αapplication␈αof
␈↓ ↓H␈↓that␈αfunction␈αwere␈αneeded,␈αthe␈α␈↓αvalue␈↓-function␈αwould␈αfind␈αthat␈αdefinition␈αand␈αapply␈α␈↓↓it␈↓␈αin␈αa␈αmanner
␈↓ ↓H␈↓analogous␈αto␈αthe␈αway␈αthe␈α
pre-defined␈αfunctions␈αare␈αapplied.␈αHow␈α
far␈αaway␈αare␈αwe␈αfrom␈α
this␈αmore
␈↓ ↓H␈↓desirable␈α
super-␈↓αvalue␈↓?␈α Well␈α
␈↓αvalue␈↓λ'␈↓␈αis␈α
already␈αwell-endowed␈α
with␈αa␈α
mechanism␈αfor␈α
locating␈αvalues;
␈↓ ↓H␈↓perhaps␈α∞we␈α∞can␈α∞exploit␈α∞this␈α∞judiciously␈α∞placed␈α∞code.␈α∞ In␈α∞what␈α∞context␈α∞would␈α∞we␈α∞be␈α∂interested␈α∞in
␈↓ ↓H␈↓locating function definitions? Here's an example:
␈↓ ↓H␈↓␈↓ B␈↓␈↓ β("What is the value of ␈↓αf[4;2;1]␈↓ when ␈↓αf[x;y;z] <= x*y + 2*z␈↓?"
␈↓ ↓H␈↓If␈α∞we␈α∂have␈α∞a␈α∞means␈α∂of␈α∞recovering␈α∞the␈α∂definition␈α∞of␈α∂␈↓αf␈↓,␈α∞then␈α∞we␈α∂can␈α∞reduce␈α∞the␈α∂problem␈α∞to␈α∂␈↓ A␈↓␈α∞of
␈↓ ↓H␈↓page 74.␈α
We␈α
will␈α
utilize␈αthe␈α
table-mechanism,␈α
and␈α
therefore␈α
will␈αuse␈α
␈↓αlocate␈↓␈α
to␈α
retrieve␈αthe␈α
definition
␈↓ ↓H␈↓of␈α∞the␈α
function␈α∞␈↓αf␈↓.␈α
In␈α∞our␈α
prior␈α∞applications␈α
of␈α∞␈↓αlocate␈↓␈α
we␈α∞would␈α
find␈α∞a␈α
constant␈α∞as␈α∞the␈α
associated
␈↓ ↓H␈↓value.␈α⊃Now,␈α⊃given␈α∩the␈α⊃name␈α⊃␈↓αf␈↓,␈α⊃we␈α∩would␈α⊃expect␈α⊃to␈α⊃find␈α∩the␈α⊃definition␈α⊃of␈α⊃the␈α∩function.␈α⊃ The
␈↓ ↓H␈↓␈↓↓78 Applications␈↓ 52.6␈↓
␈↓ ↓H␈↓question␈α∂then,␈α∂is␈α∂how␈α∂do␈α∂we␈α∂represent␈α⊂the␈α∂definition␈α∂of␈α∂␈↓αf␈↓?␈α∂ Certainly␈α∂the␈α∂body␈α∂of␈α⊂the␈α∂function,
␈↓ ↓H␈↓␈↓αx*y + 2*z␈↓,␈α
is␈αone␈α
of␈α
the␈αnecessary␈α
ingredients,␈αbut␈α
is␈α
that␈αall?␈α
Given␈α
the␈αexpression␈α
␈↓αx*y + 2*z␈↓␈αcan␈α
we
␈↓ ↓H␈↓successfully␈α∂compute␈α∂␈↓αf[4;2;1]␈↓?␈α∂ Not␈α∞yet;␈α∂we␈α∂need␈α∂to␈α∞know␈α∂the␈α∂correspondence␈α∂between␈α∂the␈α∞values
␈↓ ↓H␈↓␈↓α1, 2, 4␈↓␈αand␈αthe␈αvariables,␈α␈↓αx,␈αy,␈αz␈↓.␈αThat␈αinformation␈αis␈αpresent␈αin␈αour␈αnotation␈α␈↓αf[x;y;z] <= ...␈↓,␈αand␈αis␈αa
␈↓ ↓H␈↓crucial␈αpart␈αof␈αthe␈αdefinition␈αof␈α␈↓αf␈↓.␈α That␈αis,␈αthe␈α␈↓↓order␈↓␈αof␈αthe␈αvariables␈αappearing␈αafter␈αthe␈αfunction
␈↓ ↓H␈↓name is an integral part of the definition: ␈↓αf[y;z;x] <= x*y +2*z␈↓ defines a different function.
␈↓ ↓H␈↓Since␈αwe␈αare␈αnow␈αtalking␈αabout␈α␈↓↓representations␈↓␈αof␈αfunctions,␈αwe␈αare␈αentering␈αthe␈αrealm␈αof␈αabstract
␈↓ ↓H␈↓data␈α∂structures␈α∂again.␈α∂We␈α∂have␈α∂a␈α∂reasonable␈α∂understanding␈α∂now␈α∂of␈α∂the␈α∂essential␈α∂components␈α∂of
␈↓ ↓H␈↓such a representation. For our purposes, a function has three parts:
␈↓ ↓H␈↓␈↓ αh␈↓↓1.␈↓ A name; ␈↓αf␈↓ in the current example.
␈↓ ↓H␈↓␈↓ αh␈↓↓2.␈↓ A formal parameter list; ␈↓α[x;y;z]␈↓ here.
␈↓ ↓H␈↓␈↓ αh␈↓↓3.␈↓ A body; ␈↓αx*y + 2*z␈↓ in the example.
␈↓ ↓H␈↓We␈αdo␈α
not␈αneed␈α
a␈αcomplete␈α
study␈αof␈α
representations␈αfor␈α
functions␈αyet.␈α
For␈αour␈α
current␈αdiscussions
␈↓ ↓H␈↓we␈αcan␈αassume␈αa␈αrepresentation␈αexists,␈αand␈αthat␈αwe␈αare␈αsupplied␈αwith␈αthree␈αselectors␈αto␈αretrieve␈αthe
␈↓ ↓H␈↓components mentioned above.
␈↓ ↓H␈↓␈↓ αh␈↓↓1.␈↓␈α∂␈↓αname␈↓␈α∂selects␈α∂the␈α∞name␈α∂component␈α∂from␈α∂the␈α∞representation.␈α∂We␈α∂have␈α∂actually␈α∞seen
␈↓ ↓H␈↓␈↓ αh␈↓αname␈↓ before in the definition ␈↓αlocate␈↓ on page 75.
␈↓ ↓H␈↓␈↓ αh␈↓↓2.␈↓␈α∞␈↓αvarlist␈↓␈α∞selects␈α∞the␈α∞list␈α∞of␈α∞variables␈α∞from␈α∞the␈α∞representation.␈α∞ We␈α∞have␈α∞already␈α∞seen
␈↓ ↓H␈↓␈↓ αhthat␈α
the␈α
natural␈α
way␈α
to␈αthink␈α
about␈α
this␈α
component␈α
is␈αas␈α
a␈α
sequence.␈α
Thus␈α
the␈αname
␈↓ ↓H␈↓␈↓ αh␈↓αvarlist␈↓.
␈↓ ↓H␈↓␈↓ αh␈↓↓3.␈↓ ␈↓αbody␈↓ selects the expression which is the content of the definition.
␈↓ ↓H␈↓Given␈α⊃a␈α⊂function␈α⊃represented␈α⊂in␈α⊃the␈α⊂table␈α⊃according␈α⊂to␈α⊃these␈α⊂conventions,␈α⊃how␈α⊂do␈α⊃we␈α⊃use␈α⊂the
␈↓ ↓H␈↓information␈α↔to␈α↔effect␈α↔the␈α↔evaluation␈α↔of␈α⊗something␈α↔like␈α↔␈↓αf[4;2;1]␈↓?␈α↔ First␈α↔␈↓αvalue␈↓λ'␈↓␈α↔will␈α↔see␈α⊗the
␈↓ ↓H␈↓representation␈α⊂of␈α⊂␈↓αf[4;2;1]␈↓;␈α⊂it␈α⊂should␈α⊂recognize␈α⊂this␈α⊂as␈α⊂an␈α⊂instance␈α⊂of␈α⊂function-application␈α⊂at␈α⊂the
␈↓ ↓H␈↓following line of ␈↓αvalue␈↓λ'␈↓:
␈↓ ↓H␈↓α␈↓ ∧αisfun_args[x] → apply[fun[x];eval_args[args[x];tbl]]
␈↓ ↓H␈↓This should cause an evaluation of the arguments and then pass on the work to ␈↓αapply␈↓.
␈↓ ↓H␈↓Clever␈α
␈↓αapply␈↓␈αshould␈α
soon␈αrealize␈α
that␈α␈↓αf␈↓␈α
is␈αnot␈α
the␈α
name␈αof␈α
a␈αknown␈α
function.␈αIt␈α
should␈αthen␈α
extract
␈↓ ↓H␈↓the␈αdefinition␈αof␈α␈↓αf␈↓␈αfrom␈αthe␈αtable;␈αassociate␈αthe␈αevaluated␈αarguments␈α(␈↓α4, 2, 1␈↓)␈αwith␈αthe␈α
variables␈αof
␈↓ ↓H␈↓the␈α
parameter␈αlist␈α
(␈↓αx, y, z␈↓),␈αmaking␈α
a␈αnew␈α
table␈αwith␈α
name-value␈αpairs␈α
(␈↓α<x, 4>, <y, 2>, <z, 1>␈↓).␈α Now
␈↓ ↓H␈↓we␈α⊃are␈α∩back␈α⊃to␈α∩the␈α⊃setting␈α∩of␈α⊃problem␈α∩␈↓ A␈↓␈α⊃of␈α∩page 74.␈α⊃ We␈α∩should␈α⊃ask␈α∩␈↓αvalue␈↓λ'␈↓␈α⊃to␈α∩evaluate␈α⊃the
␈↓ ↓H␈↓␈↓αbody␈↓-component␈α∂of␈α∂the␈α⊂function␈α∂using␈α∂the␈α⊂new␈α∂␈↓αtbl␈↓.␈α∂ This␈α∂works␈α⊂fine␈α∂for␈α∂␈↓αx␈↓,␈α⊂␈↓αy␈↓,␈α∂and␈α∂␈↓αz␈↓;␈α⊂within␈α∂the
␈↓ ↓H␈↓evaluation␈αof␈αthe␈αbody␈αof␈α␈↓αf␈↓␈αwe␈αwill␈αfind␈αthe␈αright␈αbindings␈αfor␈αthese␈αvariables.␈αBut␈αwe␈αmight␈αalso
␈↓ ↓H␈↓␈↓↓2.6␈↓ λ Evaluation of Polynomials 79␈↓
␈↓ ↓H␈↓need␈α∂some␈α∂information␈α∂from␈α∂the␈α∂original␈α∂␈↓αtbl␈↓.␈α∂The␈α∂evaluation␈α∂of␈α∂the␈α∂body␈α∂of␈α∂␈↓αf␈↓␈α∂might␈α∂entail␈α∞the
␈↓ ↓H␈↓application of some function definition present in ␈↓αtbl␈↓. For example, the representation of
␈↓ ↓H␈↓␈↓ βx"what is ␈↓αg[2]␈↓ where ␈↓αg[x] <= x+s[x];␈↓ and ␈↓αs[x] <= x*x␈↓?"
␈↓ ↓H␈↓Within␈α
the␈α
body␈α
of␈α␈↓αg␈↓␈α
we␈α
need␈α
the␈α
definition␈αof␈α
␈↓αs␈↓.␈α
Therefore,␈α
instead␈αof␈α
building␈α
a␈α
new␈α
table␈αwe
␈↓ ↓H␈↓will␈αadd␈α
the␈αnew␈α
bindings␈αto␈αthe␈α
front␈αof␈α
the␈αold␈α
table.␈αSince␈α␈↓αlocate␈↓␈α
begins␈αits␈α
search␈αfrom␈αthe␈α
front
␈↓ ↓H␈↓of␈αthe␈αtable␈αwe␈αwill␈αbe␈αassured␈αof␈αfinding␈αthe␈αnew␈αbindings;␈αsince␈αthe␈αold␈αtable␈αis␈αstill␈αaccessible␈α
we
␈↓ ↓H␈↓are assured of finding any necessary previous bindings.
␈↓ ↓H␈↓We␈α
should␈α
be␈α
able␈α
to␈α
create␈α
a␈α
new␈α
␈↓αvalue␈↓λ''␈↓␈α
now.␈α
Looking␈α
at␈α
the␈α
finer␈α
detail␈α
of␈α
␈↓αvalue␈↓λ'␈↓␈α
and␈α␈↓αapply␈↓,␈α
we
␈↓ ↓H␈↓can␈αsee␈αa␈αfew␈αother␈αmodifications␈αneed␈αto␈αbe␈αmade.␈α ␈↓αapply␈↓λ'␈↓␈αwill␈αlocate␈αthe␈αfunction␈αdefinition␈αand
␈↓ ↓H␈↓thus ␈↓αtbl␈↓ should be included as a third argument to ␈↓αapply␈↓λ'␈↓. That is, inside ␈↓αapply␈↓λ'␈↓ we will have:
␈↓ ↓H␈↓␈↓ ∧;␈↓αisfun[fn] → apply␈↓λ'␈↓α[locate[fn;tbl];evargs;tbl]␈↓;
␈↓ ↓H␈↓After␈α∞␈↓αlocate␈↓␈α
has␈α∞done␈α
its␈α∞work,␈α
this␈α∞line␈α
(above)␈α∞will␈α
invoke␈α∞␈↓αapply␈↓λ'␈↓␈α
with␈α∞a␈α
function␈α∞definition␈α
as
␈↓ ↓H␈↓first argument. We'd better prepare ␈↓αapply␈↓λ'␈↓ for such an eventuality with the following addition:
␈↓ ↓H␈↓α␈↓ β←isdef[fn] → value␈↓λ''␈↓α[body[fn];newtbl[varlist[fn];evargs;tbl]];
␈↓ ↓H␈↓What does this incredible line say? It says
␈↓ ↓H␈↓␈↓ α_"Evaluate␈α∞the␈α
body␈α∞of␈α∞the␈α
function␈α∞using␈α
a␈α∞new␈α∞table␈α
manufactured␈α∞from␈α
the␈α∞old␈α∞table␈α
by
␈↓ ↓H␈↓␈↓ α_adding␈α∃the␈α∀pairings␈α∃of␈α∃the␈α∀elements␈α∃of␈α∀the␈α∃formal␈α∃parameter␈α∀list␈α∃with␈α∃the␈α∀evaluated
␈↓ ↓H␈↓␈↓ α_arguments."
␈↓ ↓H␈↓It␈α∞also␈α∂says␈α∞we'd␈α∂better␈α∞write␈α∂␈↓αnewtbl␈↓.␈α∞This␈α∂LISP␈α∞function␈α∂will␈α∞make␈α∂a␈α∞new␈α∂table␈α∞by␈α∂adding␈α∞new
␈↓ ↓H␈↓name-value␈α∩pairs␈α∩to␈α⊃an␈α∩existing␈α∩table.␈α∩ So␈α⊃we'd␈α∩better␈α∩name␈α∩a␈α⊃constructor␈α∩to␈α∩generate␈α∩a␈α⊃new
␈↓ ↓H␈↓name-value pair:
␈↓ ↓H␈↓␈↓αmkent␈↓␈αis␈αthe␈αconstructor␈αto␈αmake␈αnew␈αentries.␈αIt␈αwill␈αtake␈αtwo␈αarguments:␈αthe␈αfirst␈αwill␈αbe␈αthe␈αname,
␈↓ ↓H␈↓␈↓ α(the second will be the value.
␈↓ ↓H␈↓Since␈αwe␈α
have␈αassumed␈α
that␈αthe␈α
structure␈αof␈α
tables,␈αvariable-lists,␈α
and␈αcalling␈α
sequences␈αto␈α
functions
␈↓ ↓H␈↓are ␈↓↓all␈↓ sequences, we will write ␈↓αnewtbl␈↓ assuming this representation.
␈↓ ↓H␈↓αnewtbl[vars;vals;tbl] <=␈↓ ∧λ[null[vars] → tbl;
␈↓ ↓H␈↓α␈↓ ∧λ ␈↓
t␈↓α → concat[␈↓ ¬_mkent[first[vars];first[vals]];
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_newtbl[␈↓ ¬xrest[vars];
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_␈↓ ¬xrest[vals];
␈↓ ↓H␈↓α␈↓ ∧λ␈↓ ¬_␈↓ ¬xtbl]] ]
␈↓ ↓H␈↓␈↓↓80 Applications␈↓ 52.6␈↓
␈↓ ↓H␈↓And finally here's the new ␈↓αvalue␈↓λ''␈↓α-apply␈↓λ'␈↓ pair:
␈↓ ↓H␈↓αvalue␈↓λ''␈↓α[x;tbl] <=␈↓ β8[isconstant[x] → x;
␈↓ ↓H␈↓α␈↓ β8 isvar[x] → locate[x;tbl];
␈↓ ↓H␈↓α␈↓ β8 isfun_args[x] → apply␈↓λ'␈↓α[␈↓ ¬xfun[x];
␈↓ ↓H␈↓α␈↓ β8␈↓ ¬xeval_args[args[x];tbl];
␈↓ ↓H␈↓α␈↓ β8␈↓ ¬xtbl] ]
␈↓ ↓H␈↓αapply␈↓λ'␈↓α[fn;evargs;tbl] <=␈↓ ∧_[issum[fn] → +[arg␈↓β1␈↓α[evargs];arg␈↓β2␈↓α[evargs]];
␈↓ ↓H␈↓α␈↓ ∧_ isprod[fn] → *[arg␈↓β1␈↓α[evargs];arg␈↓β2␈↓α[evargs]];
␈↓ ↓H␈↓α␈↓ ∧_ isexpt[fn] → ↑[arg␈↓β1␈↓α[evargs];arg␈↓β2␈↓α[evargs]];
␈↓ ↓H␈↓α␈↓ ∧_ isfun[fn] → apply␈↓λ'␈↓α[locate[fn;tbl];evargs;tbl];
␈↓ ↓H␈↓α␈↓ ∧_ isdef[fn] → value␈↓λ''␈↓α[body[fn];newtbl[varlist[fn];evargs;tbl]] ]
␈↓ ↓H␈↓αeval_args[args;tbl] <=␈↓ βx[null[args] → ( );
␈↓ ↓H␈↓α␈↓ βx ␈↓
t␈↓α → concat[␈↓ ¬_value␈↓λ''␈↓α[first[args];tbl];
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬_eval_args[rest[args];tbl]] ]
␈↓ ↓H␈↓Let's␈α
go␈α
through␈αa␈α
complete␈α
evaluation␈αof␈α
␈↓ B␈↓␈α
of␈αpage 77.␈α
As␈α
before,␈αwe␈α
will␈α
use␈α␈↓
R␈↓␈α
as␈α
a␈αmapping
␈↓ ↓H␈↓from expressions to representations. Thus we want to pursue:
␈↓ ↓H␈↓␈↓ βf␈↓αvalue␈↓λ''␈↓α[␈↓
R␈↓∞(␈↓α f[4;2;1] ␈↓∞)␈↓α; ␈↓
R␈↓∞(␈↓α{ <f, [[x;y;z] x*y + 2*z]> }␈↓∞)␈↓α]␈↓.
␈↓ ↓H␈↓Let␈α∂us␈α∂denote␈α∂the␈α∂initial␈α∂symbol␈α∂table,␈α∂␈↓
R␈↓∞(␈↓α{ <f, [[x;y;z] x*y + 2*z]> }␈↓∞)␈↓␈α∂as␈α∂␈↓αinit␈↓.␈α∂This␈α∂will␈α∞simplify
␈↓ ↓H␈↓many␈αof␈αthe␈αexpressions.␈α Notice␈αthat␈αour␈αrepresentation␈αof␈α␈↓αf␈↓␈αin␈α␈↓αinit␈↓␈αhas␈αassociated␈αthe␈αvariable␈αlist
␈↓ ↓H␈↓␈↓α[x;y;z]␈↓␈α∞with␈α∞the␈α∞body␈α∞of␈α∂the␈α∞function.␈α∞Thus␈α∞␈↓αlocate␈↓,␈α∞operating␈α∞on␈α∂this␈α∞table␈α∞with␈α∞the␈α∞name␈α∂␈↓αf␈↓,␈α∞will
␈↓ ↓H␈↓return a representation of ␈↓α[[x;y;z] x*y + 2*z]␈↓.
␈↓ ↓H␈↓␈↓αisfun_args␈↓ should be satisfied and thus the computation should reduce to:
␈↓ ↓H␈↓␈↓ αe␈↓αapply␈↓λ'␈↓α[fun[ ␈↓
R␈↓∞(␈↓α f[4;2;1] ␈↓∞)␈↓α ];eval_args[args[ ␈↓
R␈↓∞(␈↓α f[4;2;1] ␈↓∞)␈↓α ]; init ];init]␈↓ or:
␈↓ ↓H␈↓␈↓ βp␈↓αapply␈↓λ'␈↓α[ ␈↓
R␈↓∞(␈↓α f ␈↓∞)␈↓α ;eval_args[ ␈↓
R␈↓∞(␈↓α [4;2;1] ␈↓∞)␈↓α; init]; init ]
␈↓ ↓H␈↓αeval_args␈↓ will build a sequence of the evaluated arguments: ␈↓α(4, 2, 1)␈↓, resulting in:
␈↓ ↓H␈↓␈↓ ∧}␈↓αapply␈↓λ'␈↓α[ ␈↓
R␈↓∞(␈↓α f ␈↓∞)␈↓α ;(4, 2, 1) ; init ]
␈↓ ↓H␈↓αapply␈↓λ'␈↓ should decide that ␈↓αf␈↓ satisfies ␈↓αisfun␈↓ giving:
␈↓ ↓H␈↓␈↓ ∧"␈↓αapply␈↓λ'␈↓α[ locate[ ␈↓
R␈↓∞(␈↓α f ␈↓∞)␈↓α ; init ]; (4, 2, 1) ; init ]␈↓
␈↓ ↓H␈↓␈↓αlocate␈↓ will retrieve the definition, and
␈↓ ↓H␈↓␈↓ β¬␈↓αapply␈↓λ'␈↓α[ ␈↓
R␈↓∞(␈↓α [[x;y;z] x*y + 2*z] ␈↓∞)␈↓α ; (4, 2, 1) ; init ]␈↓ should be the result.
␈↓ ↓H␈↓␈↓↓2.6␈↓ λ Evaluation of Polynomials 81␈↓
␈↓ ↓H␈↓Next, ␈↓αapply␈↓λ'␈↓ should realize that ␈↓
R␈↓∞(␈↓α [[x;y;z] x*y + 2*z] ␈↓∞)␈↓ satisfies ␈↓αisdef␈↓ and thus:
␈↓ ↓H␈↓␈↓ ↓V␈↓αvalue␈↓λ''␈↓α[body[ ␈↓
R␈↓∞(␈↓α [[x;y;z] x*y + 2*z] ␈↓∞)␈↓α ];newtbl[varlist[ ␈↓
R␈↓∞(␈↓α [[x;y;z] x*y + 2*z] ␈↓∞)␈↓α ];(4,2,1);init]]␈↓ or:
␈↓ ↓H␈↓␈↓ β>␈↓αvalue␈↓λ''␈↓α[ ␈↓
R␈↓∞(␈↓α [x*y + 2*z] ␈↓∞)␈↓α ;newtbl[ ␈↓
R␈↓∞(␈↓α [x;y;z] ␈↓∞)␈↓α ;(4,2,1);init]]␈↓
␈↓ ↓H␈↓after ␈↓αbody␈↓ and ␈↓αvarlist␈↓ are finished.
␈↓ ↓H␈↓␈↓
R␈↓∞(␈↓α [x;y;z] ␈↓∞)␈↓␈αis␈α␈↓α(␈↓
R␈↓∞(␈↓α x ␈↓∞)␈↓α, ␈↓
R␈↓∞(␈↓α y ␈↓∞)␈↓α, ␈↓
R␈↓∞(␈↓α z ␈↓∞)␈↓α)␈↓,␈αand␈αtherefore␈αthe␈αcomputation␈αof␈α␈↓αnewtbl␈↓␈αwill␈αbuild␈αa
␈↓ ↓H␈↓new table with entries for ␈↓αx, y, ␈↓ and ␈↓αz␈↓ on the front:
␈↓ ↓H␈↓␈↓ β|␈↓
R␈↓∞(␈↓α{ <x, 4>, <y, 2>, <z, 1>, <f, [[x;y;z] x*y + 2*z]> }␈↓∞)␈↓.
␈↓ ↓H␈↓Thus we call ␈↓αvalue␈↓λ''␈↓ with:
␈↓ ↓H␈↓␈↓ α>␈↓αvalue␈↓λ''␈↓α[ ␈↓
R␈↓∞(␈↓α [x*y + 2*z] ␈↓∞)␈↓α; ␈↓
R␈↓∞(␈↓α{ <x, 4>, <y, 2>, <z, 1>, <f, [[x;y;z] x*y + 2*z]> }␈↓∞)␈↓α ]␈↓.
␈↓ ↓H␈↓Now we're back at problem ␈↓ A␈↓ of page 74.
␈↓ ↓H␈↓␈↓ ¬Q␈↓↓Time to take stock␈↓
␈↓ ↓H␈↓We␈α∞have␈α∞written␈α∞a␈α∞reasonably␈α∞sophisticated␈α∞algorithm␈α∞here;␈α∞we␈α∞should␈α∞examine␈α∞the␈α∞results␈α
quite
␈↓ ↓H␈↓carefully.␈α
Notice␈αthat␈α
we␈αhave␈α
written␈αthe␈α
algorithm␈α
with␈αalmost␈α
no␈αconcern␈α
for␈αrepresentation.␈α
We
␈↓ ↓H␈↓␈↓↓assume␈↓␈α
that␈α
representations␈α
are␈α
available␈α
for␈αsuch␈α
varied␈α
things␈α
as␈α
arithmetic␈α
expressions,␈αtables,
␈↓ ↓H␈↓calls␈αon␈αfunctions,␈α
and␈αeven␈αfunction␈αdefinitions.␈α
Very␈αseldom␈αdid␈α
we␈αcommit␈αourselves␈αto␈α
anything
␈↓ ↓H␈↓close␈α∞to␈α∞a␈α∞concrete␈α∞representation,␈α∞and␈α∞then␈α∞only␈α∞with␈α∞great␈α∞reluctance.␈α∞It␈α∞was␈α∞with␈α∞some␈α∞sadness
␈↓ ↓H␈↓that␈αwe␈αimposed␈αa␈αsequencing␈αon␈αelements␈αof␈αtables.␈α Variable␈αlists␈αand␈αcalling␈αsequences␈αwere␈αnot
␈↓ ↓H␈↓as␈αtraumatic;␈αwe␈αclaimed␈αtheir␈αnatural␈αstructure␈αwas␈αa␈αsequence.␈αAs␈αalways,␈αif␈αwe␈αwish␈αto␈αrun␈αthese
␈↓ ↓H␈↓programs␈α
on␈α
a␈α
machine␈α
we␈α
must␈α
supply␈α
some␈α
representations,␈α
but␈α
even␈α
then␈α
the␈α
representations␈α
will
␈↓ ↓H␈↓only interface with our algorithms at the constructors, selectors and recognizers.
␈↓ ↓H␈↓We␈αhave␈αmade␈αsome␈αmore␈αserious␈αrepresentational␈αdecisions␈αin␈αthe␈αstructure␈αof␈αthe␈αalgorithm.␈α We
␈↓ ↓H␈↓have␈α
encoded␈α
a␈α
version␈α
of␈α
the␈α
␈↓ CBV␈↓-scheme␈α∞of␈α
page 16.␈α
We␈α
have␈α
seen␈α
what␈α
kinds␈α∞of␈α
difficulties
␈↓ ↓H␈↓that␈α∂can␈α∂cause.␈α∂We␈α∂will␈α∞spend␈α∂a␈α∂large␈α∂amount␈α∂of␈α∞time␈α∂in␈α∂Chapter 3␈α∂discussing␈α∂the␈α∂problems␈α∞of
␈↓ ↓H␈↓evaluation␈↓π 50␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 50␈↓␈α
A␈α
second␈α
decision␈α
was␈α
implied␈α
in␈α
our␈α
handling␈α
of␈α
function␈α
definitions;␈α
namely␈α
we␈α∞bound␈α
the
␈↓ ↓H␈↓function␈α
name␈α∞to␈α
a␈α
structure␈α∞consisting␈α
of␈α
the␈α∞formal␈α
parameter␈α
list␈α∞and␈α
the␈α
function␈α∞body.␈α
This
␈↓ ↓H␈↓representation␈α∞gives␈α∞the␈α∞expected␈α∂result␈α∞in␈α∞most␈α∞cases,␈α∞but␈α∂involves␈α∞one␈α∞of␈α∞the␈α∂more␈α∞problematic
␈↓ ↓H␈↓areas␈αof␈αprogramming␈αlanguages:␈αhow␈αdo␈αyou␈αfind␈αthe␈αbindings␈αof␈αvariables␈αwhich␈αdo␈αnot␈αappear
␈↓ ↓H␈↓in␈α⊂the␈α⊂current␈α⊂variable␈α⊃list?␈α⊂Function␈α⊂names␈α⊂belong␈α⊂in␈α⊃this␈α⊂category.␈α⊂Such␈α⊂variables␈α⊃are␈α⊂called
␈↓ ↓H␈↓non-local␈αvariables.␈αThe␈αscheme␈α
proposed␈αin␈αthis␈αsection␈αfinds␈α
the␈αbinding␈αwhich␈αis␈α
current␈αwhen
␈↓ ↓H␈↓␈↓↓82 Applications␈↓ 52.6␈↓
␈↓ ↓H␈↓Finally,␈αour␈αdecisions␈αon␈αthe␈αdata␈αstructures␈αand␈αthe␈αalgorithms␈αwere␈αnot␈αmade␈αindependently.␈αFor
␈↓ ↓H␈↓example,␈αthere␈αis␈αstrong␈αinteraction␈αbetween␈αour␈αrepresentation␈αof␈αtables␈αand␈αthe␈αalgorithms,␈α␈↓αlocate␈↓
␈↓ ↓H␈↓and␈α␈↓αnewtbl␈↓␈αwhich␈αmanipulate␈αthose␈αtables.␈αWe␈αshould␈αask␈αhow␈αmuch␈αof␈αthis␈αinteraction␈αis␈αinherent
␈↓ ↓H␈↓and␈α∂how␈α∂much␈α∞is␈α∂gratuitous.␈α∂For␈α∂example,␈α∞we␈α∂have␈α∂remarked␈α∞that␈α∂our␈α∂representation␈α∂can␈α∞have
␈↓ ↓H␈↓pairs␈αwith␈αduplicate␈αfirst␈αelements.␈αIt␈αis␈αthe␈αresponsibility␈αof␈α␈↓αlocate␈↓␈αto␈αsee␈αthat␈αwe␈αfind␈αthe␈αexpected
␈↓ ↓H␈↓pair.␈α
If␈α
we␈α
wrote␈α␈↓αlocate␈↓␈α
to␈α
search␈α
from␈α
right␈αto␈α
left,␈α
we␈α
could␈α
get␈αthe␈α
wrong␈α
pair.␈α
We␈α
␈↓↓could␈↓␈αwrite
␈↓ ↓H␈↓␈↓αnewtbl␈↓ to be more selective; it could manufacture a table without such duplications:
␈↓ ↓H␈↓αnewtbl[vars;vals;tbl] <=␈↓ βx[null[tbl] →␈↓ ¬_[null[vars] → ();
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬_ ␈↓
t␈↓α → concat[␈↓ ε(mkent[first[vars];first[vals]];
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬_␈↓ ε(newtbl[rest[vars];rest[vals];( )]]];
␈↓ ↓H␈↓α␈↓ βx member[name[first[tbl]];vars] → newtbl[vars;vals;rest[tbl]];
␈↓ ↓H␈↓α␈↓ βx ␈↓
t␈↓α → concat[first[tbl];newtbl[vars;vals;rest[tbl]]] ]
␈↓ ↓H␈↓This␈αversion␈αof␈α
␈↓αnewtbl␈↓␈αrequires␈αmuch␈αmore␈α
computation␈αthan␈αthe␈α
alternative.␈α Its␈αadvantage␈αis␈α
that
␈↓ ↓H␈↓the␈α"set"-ness␈αof␈αsymbol␈αtables␈αis␈αmaintained.␈αThe␈α"set"␈αproperty␈αis␈αone␈αwhich␈αwe␈αneed␈αnot␈αdepend
␈↓ ↓H␈↓on␈α
for␈α
our␈α
algorithms;␈α
in␈α
fact,␈α
we␈α
will␈α
frequently␈α
expect␈α
that␈α
a␈α
table␈α
is␈α
represented␈α
as␈α
a␈αsequence
␈↓ ↓H␈↓with the previous values of variables found further along in the sequence.
␈↓ ↓H␈↓The␈α∂main␈α⊂point␈α∂of␈α⊂this␈α∂example␈α∂however␈α⊂is␈α∂to␈α⊂impress␈α∂on␈α∂you␈α⊂the␈α∂importance␈α⊂of␈α∂writing␈α⊂at␈α∂a
␈↓ ↓H␈↓sufficiently␈αhigh␈αlevel␈αof␈αabstraction.␈αWe␈αhave␈α
produced␈αa␈αnon-trivial␈αalgorithm␈αwhich␈αis␈αclear␈α
and
␈↓ ↓H␈↓concise.␈αIf␈αit␈αwere␈αdesirable␈αto␈αhave␈αthis␈αalgorithm␈αrunning␈αon␈αa␈αmachine␈αwe␈αcould␈αcode␈αit␈αand␈αits
␈↓ ↓H␈↓associated␈αdata␈αstructure␈αrepresentations␈αin␈αa␈αvery␈αshort␈αtime.␈α In␈αa␈αvery␈αshort␈αtime␈α␈↓↓we␈↓␈αwill␈αbe␈αable
␈↓ ↓H␈↓to run this algorithm on a LISP machine.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓On␈α
page 74␈α
we␈α
mentioned␈α
the␈α
possibility␈α
of␈α
writing␈α
the␈α
new␈α
␈↓αvalue␈↓␈α
as␈α
a␈α
combination␈α
of␈α
old␈α␈↓αvalue␈↓
␈↓ ↓H␈↓and␈α␈↓αinstantiate␈↓.␈αWe␈αrejected␈αthat␈αscheme.␈αOn␈αpage 79␈αwe␈αhad␈αto␈αsave␈αan␈αold␈αtable␈αsince␈αwe␈αmight
␈↓ ↓H␈↓need␈α∀some␈α∀previously␈α∀defined␈α∀functions.␈α∀We␈α∀might␈α∪not␈α∀have␈α∀had␈α∀this␈α∀difficulty␈α∀if␈α∀we␈α∪had
␈↓ ↓H␈↓substituted directly. Write a substitution-type ␈↓αvalue␈↓ and use it to evaluate the ␈↓αg[2]␈↓ example.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓the␈αfunction␈αwas␈αapplied.␈αSome␈αprogramming␈α
languages␈αfollow␈αthis;␈αsome␈αother␈αlanguages␈α
advocate
␈↓ ↓H␈↓finding␈αthe␈αbinding␈α
which␈αwas␈αcurrent␈α
when␈αthe␈αfunction␈αwas␈α
defined,␈αand␈αsome␈α
languages␈αallow
␈↓ ↓H␈↓both. The next two chapters begin a study of binding strategies.
␈↓ ↓H␈↓␈↓↓2.7␈↓ The Great Mothers 83␈↓
␈↓ ↓H␈↓␈↓ ¬6␈↓↓2.7 The Great Mothers␈↓
␈↓ ↓H␈↓The␈αfollowing␈αproblems␈αare␈α
written␈α(intentionally)␈αwith␈αa␈αgreat␈α
deal␈αof␈αthe␈αrepresentation␈αbuilt␈α
into
␈↓ ↓H␈↓them.
␈↓ ↓H␈↓␈↓ ∧≤␈↓↓I. The Great Mother of All Functions (␈↓αtgmoaf␈↓↓)
␈↓ ↓H␈↓α␈↓ ↓Htgmoaf[x] <=␈↓ β8[isindiv[x] →␈↓ ∧h[eq[x ;T] → ␈↓
t␈↓α;
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8␈↓ ∧h eq[x;NIL] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8␈↓ ∧h ␈↓
t␈↓α → TRYAGAINNEXTWEEK];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];QUOTE] → second[x];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];CAR] → car[tgmoaf[second[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];CDR] → cdr[tgmoaf[second[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];CONS] → cons[tgmoaf[second[x]];tgmoaf[third[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];ATOM] → atom[tgmoaf[second[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];EQ] → eq[tgmoaf[second[x]];tgmoaf[third[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 ␈↓
t␈↓α → TRYAGAINNEXTWEEK]
␈↓ ↓H␈↓Evaluate the following:
␈↓ ↓H␈↓␈↓↓1.␈↓α tgmoaf[T]
␈↓ ↓H␈↓α␈↓↓2.␈↓α tgmoaf[A]
␈↓ ↓H␈↓α␈↓↓3.␈↓α tgmoaf[(CAR (QUOTE (A . B)))]
␈↓ ↓H␈↓α␈↓↓4.␈↓α tgmoaf[(CDR (QUOTE (A B)))]
␈↓ ↓H␈↓α␈↓↓5.␈↓α tgmoaf[(EQ (CAR (QUOTE (A . B))) (QUOTE A))]
␈↓ ↓H␈↓α␈↓↓6.␈↓α tgmoaf[(EQ (CAR (QUOTE (A . B))) A)]
␈↓ ↓H␈↓α␈↓↓7.␈↓α tgmoaf[(ATOM (CAR (QUOTE (A B))))]
␈↓ ↓H␈↓α␈↓ βM␈↓↓II. The Great Mother of All Functions Revisited (␈↓αtgmoafr␈↓↓)
␈↓ ↓H␈↓α␈↓ ↓Htgmoafr[x] <=␈↓ β8[isindiv[x] →␈↓ ∧h[eq[x;T] → ␈↓
t␈↓α;
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8␈↓ ∧h eq[x;NIL] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8␈↓ ∧h ␈↓
t␈↓α → TRYAGAINNEXTWEEK];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];QUOTE] → second[x];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];CAR] → car[tgmoafr[second[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];CDR] → cdr[tgmoafr[second[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];CONS] → cons[tgmoafr[second[x]];tgmoafr[third[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];ATOM] → atom[tgmoafr[second[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];EQ] → eq[tgmoafr[second[x]];tgmoafr[third[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 eq[first[x];COND] → evcond[rest[x]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 ␈↓
t␈↓α → TRYAGAINNEXTWEEK]
␈↓ ↓H␈↓␈↓↓84 Applications␈↓ 52.7␈↓
␈↓ ↓H␈↓α␈↓ ↓Hevcond[x] <=␈↓ β8[tgmoafr[first[first[x]]] → tgmoafr[second[first[x]]];
␈↓ ↓H␈↓α␈↓ ↓H␈↓ β8 ␈↓
t␈↓α → evcond[rest[x]] ]
␈↓ ↓H␈↓Evaluate the following:
␈↓ ↓H␈↓␈↓↓1.␈↓α tgmoafr[T]
␈↓ ↓H␈↓α␈↓↓2.␈↓α tgmoafr[(CDR (QUOTE (A B)))]
␈↓ ↓H␈↓α␈↓↓3.␈↓α tgmoafr[(EQ (CAR (QUOTE (A . B))) (QUOTE A))]
␈↓ ↓H␈↓α␈↓↓4.␈↓α tgmoafr[(COND ((EQ (CAR (QUOTE (A . B))) (QUOTE A)) (QUOTE FOO)))]
␈↓ ↓H␈↓α␈↓↓5.␈↓α tgmoafr[(COND ((ATOM (QUOTE (A))) (QUOTE FOO)) (T (QUOTE BAZ)))]
␈↓ ↓H␈↓α␈↓ ∧cComing soon: ␈↓↓Son of Great Mother !!␈↓α
␈↓ ↓H␈↓␈↓ ¬G␈↓↓2.8 Another Respite␈↓
␈↓ ↓H␈↓We␈αhave␈αagain␈α
reached␈αa␈αpoint␈αwhere␈α
a␈αcertain␈αamount␈αof␈α
reflection␈αwould␈αbe␈αbeneficial.␈α
Though
␈↓ ↓H␈↓this␈α
is␈α
not␈α
a␈α
programming␈α
manual␈α
we␈α
would␈α
be␈αremiss␈α
if␈α
we␈α
did␈α
not␈α
attempt␈α
to␈α
analyze␈α
the␈αstyle
␈↓ ↓H␈↓which we have tried to exercise when writing programs.
␈↓ ↓H␈↓1.␈αWrite␈αthe␈αalgorithm␈α
in␈αan␈αabstract␈αsetting;␈α
do␈αnot␈αmuddle␈αthe␈α
abstract␈αalgorithm␈αwith␈αthe␈α
chosen
␈↓ ↓H␈↓representation.␈α∞ If␈α∂you␈α∞follow␈α∞this␈α∂dictum␈α∞your␈α∞LISP␈α∂programs␈α∞will␈α∞never␈α∂use␈α∞␈↓αcar,␈α∞cdr,␈α∂cons␈↓,␈α∞and
␈↓ ↓H␈↓␈↓αatom␈↓,␈α∀and␈α∀rarely␈α∀use␈α∃␈↓αeq␈↓.␈α∀ All␈α∀instances␈α∀of␈α∀these␈α∃LISP␈α∀primitives␈α∀will␈α∀be␈α∀relegated␈α∃to␈α∀small
␈↓ ↓H␈↓subfunctions which manipulate representations.
␈↓ ↓H␈↓2.␈α∀When␈α∀writing␈α∃the␈α∀abstract␈α∀program,␈α∃do␈α∀not␈α∀be␈α∃afraid␈α∀to␈α∀cast␈α∃off␈α∀difficult␈α∀parts␈α∃of␈α∀the
␈↓ ↓H␈↓implementation␈α∞to␈α∞subfunctions.␈α∞Remember␈α∞that␈α∞if␈α
you␈α∞have␈α∞trouble␈α∞keeping␈α∞the␈α∞details␈α∞in␈α
mind
␈↓ ↓H␈↓when␈α␈↓↓writing␈↓␈αthe␈α
program,␈αthen␈αthe␈αconfusion␈α
involved␈αin␈α␈↓↓reading␈↓␈αthe␈α
program␈αat␈αsome␈αlater␈α
time
␈↓ ↓H␈↓will␈α∀be␈α∀overwhelming.␈α∃Once␈α∀you␈α∀have␈α∃convinced␈α∀yourself␈α∀of␈α∃the␈α∀correctness␈α∀of␈α∃the␈α∀current
␈↓ ↓H␈↓composition,␈α∂then␈α∂worry␈α∂about␈α∂the␈α∂construction␈α∂of␈α∂the␈α∂subfunctions.␈α∂Seldom␈α∂does␈α∂the␈α⊂process␈α∂of
␈↓ ↓H␈↓composing␈α∀a␈α∀program␈α∀flow␈α∀so␈α∀gently␈α∀from␈α∀top-level␈α∀to␈α∀specific␈α∀representation.␈α∀Only␈α∀the␈α∪toy
␈↓ ↓H␈↓programs␈α∞are␈α∂easy;␈α∞the␈α∂construction␈α∞of␈α∂the␈α∞practical␈α∞program␈α∂will␈α∞be␈α∂confusing,␈α∞and␈α∂will␈α∞require
␈↓ ↓H␈↓much rethinking. But bring as much structure as you can to the process.
␈↓ ↓H␈↓3.␈α⊂From␈α⊂the␈α⊂other␈α⊂side␈α⊂of␈α⊂the␈α⊂question,␈α⊂don't␈α⊂be␈α⊂afraid␈α⊂to␈α⊂look␈α⊂at␈α⊂specific␈α⊃implementations,␈α⊂or
␈↓ ↓H␈↓specific␈α⊗data-structure␈α⊗representations␈α↔before␈α⊗you␈α⊗begin␈α⊗to␈α↔write.␈α⊗There␈α⊗is␈α↔something␈α⊗quite
␈↓ ↓H␈↓comforting␈α⊂about␈α⊂a␈α⊂"real"␈α⊂data␈α⊂structure.␈α⊂Essentially␈α⊂data␈α⊂structures␈α⊂are␈α⊂static␈α⊂objects␈α⊃␈↓π 51␈↓,␈α⊂while
␈↓ ↓H␈↓programs␈α∂are␈α∂dynamic␈α∂objects.␈α∂A␈α∂close␈α∂look␈α∂at␈α∂a␈α∂possible␈α∂representation␈α∂may␈α∂get␈α∂you␈α⊂a␈α∂starting
␈↓ ↓H␈↓point␈αand␈αas␈αyou␈αwrite␈αthe␈αprogram␈αa␈αdistinction␈αwill␈αemerge␈αbetween␈αa␈αdependence␈αon␈αthe␈αspecific
␈↓ ↓H␈↓representation and the use of properties of an abstract data structure.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 51␈↓ At least within the program presently being constructed.
␈↓ ↓H␈↓␈↓↓2.8␈↓ .Another Respite 85␈↓
␈↓ ↓H␈↓Perhaps␈α∂the␈α∂more␈α∂practical␈α∞reader␈α∂is␈α∂overcome␈α∂by␈α∞the␈α∂inefficiencies␈α∂inherent␈α∂in␈α∂these␈α∞proposals.
␈↓ ↓H␈↓Two␈α
answers:␈α
first,␈α∞"inefficiency"␈α
is␈α
a␈α∞very␈α
ethereal␈α
concept.␈α∞ Like␈α
"structured␈α
programming",␈α∞it␈α
is
␈↓ ↓H␈↓difficult␈α⊃to␈α⊂define␈α⊃but␈α⊃recognizable␈α⊂when␈α⊃it␈α⊂occurs.␈α⊃ Hardware␈α⊃development␈α⊂has␈α⊃enabled␈α⊃us␈α⊂to
␈↓ ↓H␈↓efficiently␈α
execute␈αmany␈α
operations␈α
which␈αwere␈α
quite␈α
inefficient␈αon␈α
earlier␈α
machines.␈α But␈α
even␈αat␈α
a
␈↓ ↓H␈↓more␈αtopical␈αlevel,␈αmuch␈αof␈αwhat␈αseems␈αinefficient␈αcan␈αnow␈αbe␈αstraightened␈αout␈αby␈αa␈αcompiler␈α(see
␈↓ ↓H␈↓Chapter 6).␈αFrequently,␈αcompilers␈αcan␈αdo␈αvery␈α
clever␈αoptimizations␈αto␈αgenerate␈αefficient␈αcode.␈α
It␈αis
␈↓ ↓H␈↓better to leave the cleverness to the compiler, and the clarity to the programmer.
␈↓ ↓H␈↓The␈α
current␈α
problems␈α
in␈αprogramming␈α
are␈α
not␈α
those␈α
of␈αefficiency;␈α
they␈α
are␈α
problems␈αof␈α
␈↓↓correctness␈↓.
␈↓ ↓H␈↓That␈αis,␈αwe␈αhave␈αa␈αbetter␈αgrasp␈αof␈αtechniques␈αfor␈αimproving␈αefficiency␈αof␈αprograms␈αthan␈αwe␈αdo␈αof
␈↓ ↓H␈↓techniques␈α∞for␈α∞guiding␈α∞the␈α∞construction␈α∞of␈α∞programs␈α∞which␈α∞work.␈α∞ How␈α∞do␈α∞you␈α∞write␈α∞a␈α
program
␈↓ ↓H␈↓which␈α⊗works?␈α⊗ Until␈α⊗practical␈α∃tools␈α⊗are␈α⊗developed␈α⊗for␈α⊗proving␈α∃correctness␈α⊗it␈α⊗is␈α⊗up␈α⊗to␈α∃the
␈↓ ↓H␈↓programmer␈αto␈αcertify␈αhis␈αprograms.␈αAny␈αmethodology␈αwhich␈αcan␈αaid␈αthe␈αprogrammer␈αwill␈αbe␈α
most
␈↓ ↓H␈↓welcome.␈α
Clearly,␈α
the␈α
closer␈α
you␈α
can␈α
write␈α
the␈α
program␈α
to␈α
your␈α
intuition,␈α
the␈α
less␈α
chance␈α
there␈αis
␈↓ ↓H␈↓for␈α
error.␈α
This␈α
was␈αone␈α
of␈α
the␈α
reasons␈α
for␈αdeveloping␈α
high-level␈α
languages.␈α
The␈αoriginal␈α
motivation
␈↓ ↓H␈↓for␈α∩such␈α⊃languages␈α∩was␈α⊃a␈α∩convenient␈α∩notation␈α⊃for␈α∩expressing␈α⊃numerical␈α∩problems.␈α∩ With␈α⊃data
␈↓ ↓H␈↓structures,␈α⊂we␈α⊂are␈α⊂able␈α⊂to␈α⊂formalize␈α⊂a␈α⊃broader␈α⊂range␈α⊂of␈α⊂domains,␈α⊂expressing␈α⊂our␈α⊂ideas␈α⊃as␈α⊂data
␈↓ ↓H␈↓structure manipulations rather than as numerical relationships.
␈↓ ↓H␈↓There␈α
are␈αat␈α
least␈α
two␈αkinds␈α
of␈αerrors␈α
which␈α
are␈αprevalent␈α
in␈α
data␈αstructure␈α
programming:␈αerrors␈α
of
␈↓ ↓H␈↓omission -- misunderstanding␈α∩of␈α⊃the␈α∩basic␈α⊃algorithm;␈α∩and␈α⊃errors␈α∩of␈α⊃commission -- errors␈α∩due␈α⊃to
␈↓ ↓H␈↓misapplied cleverness in attempting to be efficient.
␈↓ ↓H␈↓The␈αoccurrences␈αof␈αerrors␈αof␈αomission␈αcan␈αbe␈αminimized␈αby␈αpresenting␈αthe␈αuser␈αwith␈αprogramming
␈↓ ↓H␈↓constructs␈α∂which␈α∂are␈α∂close␈α∂to␈α∂the␈α∂informal␈α∂algorithm.␈α∂ Such␈α∂constructs␈α∂include␈α∂control␈α∞structures,
␈↓ ↓H␈↓data structures, and representations for operations.
␈↓ ↓H␈↓Errors␈α∂of␈α∂commission␈α∂comprise␈α∂the␈α∂great␈α∂majority␈α∂of␈α∂the␈α∂present␈α∂day␈α∂headaches.␈α∂It␈α∂is␈α⊂here␈α∂that
␈↓ ↓H␈↓programming␈α␈↓↓style␈↓␈αcan␈αbe␈αbeneficial:␈αkeep␈αthe␈αrepresentation␈αof␈αthe␈αdata␈αstructures␈αaway␈αfrom␈αthe
␈↓ ↓H␈↓description␈α∃of␈α∃the␈α∃algorithm;␈α∃write␈α∃concise␈α∃abstract␈α∃programs,␈α∃passing␈α∃off␈α⊗responsibilities␈α∃to
␈↓ ↓H␈↓subfunctions.␈α⊂Whenever␈α⊂a␈α⊂definition␈α⊂of␈α⊂"structured␈α⊂programming"␈α⊂is␈α⊂arrived␈α⊂at,␈α⊂this␈α⊃advice␈α⊂on
␈↓ ↓H␈↓programming style will no doubt be included.
␈↓ ↓H␈↓Before␈α⊃closing␈α⊃this␈α⊃discussion␈α⊃of␈α⊃LISP␈α⊃programming␈α⊃style,␈α⊃we␈α⊃can't␈α⊃help␈α⊃but␈α⊃note␈α⊃that␈α⊃in␈α⊂the
␈↓ ↓H␈↓preceding␈αsection,␈α
␈↓↓The␈αGreat␈α
Mothers␈↓␈αhave␈α
completely␈αignored␈αour␈α
good␈αadvice.␈α
This␈αwould␈α
be␈αa
␈↓ ↓H␈↓good␈α⊃time␈α⊃for␈α⊃the␈α⊃interested␈α⊃reader␈α⊃to␈α⊂abstract␈α⊃the␈α⊃␈↓αtgmoaf␈↓␈α⊃algorithm␈α⊃from␈α⊃the␈α⊃particular␈α⊂data
␈↓ ↓H␈↓representation. This detective work will be most rewarding.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Write an abstract version of ␈↓αtgmoaf␈↓.
␈↓ ↓H␈↓␈↓↓86 Applications␈↓ 52.9␈↓
␈↓ ↓H␈↓␈↓ ∧\␈↓↓2.9 Proving Properties of Programs␈↓
␈↓ ↓H␈↓People␈α
are␈α
becoming␈αincreasingly␈α
aware␈α
of␈αthe␈α
importance␈α
of␈αgiving␈α
convincing␈α
arguments␈αfor␈α
such
␈↓ ↓H␈↓concepts␈α∞as␈α
the␈α∞correctness␈α∞or␈α
equivalence␈α∞of␈α
programs.␈α∞These␈α∞are␈α
both␈α∞very␈α∞difficult␈α
enterprises.
␈↓ ↓H␈↓We␈αwill␈αsketch␈αa␈αproof␈αof␈αa␈αsimple␈αproperty␈αof␈αtwo␈αprograms␈αand␈αleave␈αothers␈αas␈αproblems␈αfor␈αthe
␈↓ ↓H␈↓interested␈αreader.␈α How␈αdo␈αyou␈αgo␈αabout␈αproving␈αproperties␈αof␈αprograms?␈α In␈αSection 1.9␈αwe␈αnoted
␈↓ ↓H␈↓certain␈αbenefits␈αof␈αdefining␈αsets␈αusing␈αinductive␈αdefinitions.␈α There␈αwas␈αa␈αnatural␈αway␈α
of␈αthinking
␈↓ ↓H␈↓about␈α
the␈α∞construction␈α
of␈α∞an␈α
algorithm␈α∞over␈α
that␈α∞set.␈α
We␈α∞have␈α
exploited␈α∞that␈α
observation␈α∞in␈α
our
␈↓ ↓H␈↓study␈α∂of␈α∂LISP␈α⊂programming.␈α∂We␈α∂need␈α⊂to␈α∂recall␈α∂the␈α∂observation␈α⊂that␈α∂inductive␈α∂style␈α⊂proofs␈α∂(see
␈↓ ↓H␈↓␈↓ PRF␈↓␈α
on␈α
page 41)␈α∞are␈α
valid␈α
forms␈α
of␈α∞reasoning␈α
over␈α
such␈α
domains.␈α∞Since␈α
we␈α
in␈α
fact␈α∞defined␈α
our
␈↓ ↓H␈↓data␈α
structure␈α
domains␈α∞in␈α
an␈α
inductive␈α∞manner,␈α
it␈α
seems␈α
natural␈α∞to␈α
look␈α
for␈α∞inductive␈α
arguments
␈↓ ↓H␈↓when␈α∞proving␈α∞properties␈α∞of␈α∞programs.␈α∞This␈α∞is␈α∞indeed␈α∞what␈α∞we␈α∞do;␈α∞we␈α∞perform␈α∞induction␈α∞on␈α∞the
␈↓ ↓H␈↓structure of the elements in the data domain.
␈↓ ↓H␈↓For␈αexample,␈αgiven␈αthe␈αdefinition␈αof␈α␈↓αappend␈↓␈αgiven␈αon␈αpage 46␈αand␈αthe␈αdefinition␈αof␈α␈↓αreverse␈↓␈αgiven
␈↓ ↓H␈↓on page 47,
␈↓ ↓H␈↓αappend[x;y] <= [null[x] → y; ␈↓
t␈↓α → concat[first[x];append[rest[x];y]]]
␈↓ ↓H␈↓αreverse[x] <=␈↓ βλ[null[x] → ( );
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α → append[reverse[rest[x]];concat[first[x];( )]]]
␈↓ ↓H␈↓we wish to show that:
␈↓ ↓H␈↓␈↓ ∧α␈↓αappend[reverse[y];reverse[x]] = reverse[append[x;y]]␈↓,
␈↓ ↓H␈↓for any lists, ␈↓αx␈↓, and ␈↓αy␈↓. The induction will be on the structure of ␈↓αx␈↓.
␈↓ ↓H␈↓␈↓ αλ␈↓↓Basis␈↓: ␈↓αx␈↓ is ␈↓α( )␈↓.
␈↓ ↓H␈↓␈↓ αλWe must thus show: ␈↓αappend[reverse[y];( )] = reverse[append[( );y]]␈↓
␈↓ ↓H␈↓␈↓ αλBut: ␈↓αreverse[append[( );y]] = reverse[y]␈↓ by the def. of ␈↓αappend␈↓.
␈↓ ↓H␈↓␈↓ αλWe now establish the stronger result: ␈↓αappend[z;( )] = z␈↓ ␈↓π 52␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓ αX␈↓↓Basis:␈↓ ␈↓αz␈↓ is ␈↓α( )␈↓.
␈↓ ↓H␈↓␈↓ αλ␈↓ αXShow ␈↓αappend[( );( )] = ( )␈↓. Easy.
␈↓ ↓H␈↓␈↓ αλ␈↓ αX␈↓↓Induction step:␈↓ Assume the lemma for lists, ␈↓αz␈↓, of length n;
␈↓ ↓H␈↓␈↓ αλ␈↓ αXProve: ␈↓αappend[concat[x;z];( )] = concat[x;z]␈↓.
␈↓ ↓H␈↓␈↓ αλ␈↓ αXSince ␈↓αconcat[...]␈↓ is not ␈↓α( )␈↓, then applying the definition of ␈↓αappend␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓ αXsays we must prove: ␈↓αconcat[x;append[z;( )]] = concat[x;z]␈↓.
␈↓ ↓H␈↓␈↓ αλ␈↓ αXBut our induction hypothesis is applicable since ␈↓αz␈↓ is shorter than ␈↓αconcat[x;z]␈↓.
␈↓ ↓H␈↓␈↓ αλ␈↓ αXOur result follows.
␈↓ ↓H␈↓␈↓ αλSo the Basis for our main result is established.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 52␈↓ In the following proof several intermediate steps have been omitted.
␈↓ ↓H␈↓␈↓↓2.9␈↓ πXProving Properties of Programs 87␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓↓Induction step:␈↓ Assume the result for lists, ␈↓αz␈↓, of length n;
␈↓ ↓H␈↓␈↓ αλProve:
␈↓ ↓H␈↓␈↓ αλ␈↓ α` (1) ␈↓αappend[reverse[y];reverse[concat[x;z]]] = reverse[append[concat[x;z];y]]␈↓
␈↓ ↓H␈↓␈↓ αλ Applying the definition of ␈↓αreverse␈↓ to the LHS of (1) yields:
␈↓ ↓H␈↓␈↓ αλ␈↓ β↑ (2) ␈↓αappend[reverse[y];append[reverse[z];concat[x;( )]]]␈↓.
␈↓ ↓H␈↓␈↓ αλ Applying the definition of ␈↓αappend␈↓ to the RHS of (1) yields:
␈↓ ↓H␈↓␈↓ αλ␈↓ ∧b (3) ␈↓αreverse[concat[x;append[z;y]]].␈↓
␈↓ ↓H␈↓␈↓ αλ Applying the definition of ␈↓αreverse␈↓ to (3) yields:
␈↓ ↓H␈↓␈↓ αλ␈↓ ∧∪ (4) ␈↓αappend[reverse[append[z;y]];concat[x;( )]].␈↓
␈↓ ↓H␈↓␈↓ αλ Using our induction hypothesis on (4) gives:
␈↓ ↓H␈↓␈↓ αλ␈↓ βa (5) ␈↓αappend[append[reverse[y];reverse[z]];concat[x;( )]]␈↓
␈↓ ↓H␈↓␈↓ αλ At this point we must establish that (2) = (5).
␈↓ ↓H␈↓␈↓ αλ But this is just an instance of the associativity of ␈↓αappend␈↓:
␈↓ ↓H␈↓␈↓ αλ␈↓ αz␈↓αappend[x;append[y;z]] = append[append[x;y];z].␈↓ (See problem I, below.)
␈↓ ↓H␈↓The␈αstructure␈αof␈αthe␈αproof␈αis␈αanalogous␈αto␈αproofs␈αby␈αmathematical␈αinduction␈αin␈αelementary␈α
number
␈↓ ↓H␈↓theory.␈αThe␈αability␈αto␈αperform␈αsuch␈αproofs␈αis␈αa␈αdirect␈αconsequence␈αof␈αour␈αcareful␈αdefinition␈αof␈αdata
␈↓ ↓H␈↓structures.␈α Examination␈αof␈αthe␈αproof␈αwill␈αshow␈αthat␈αthere␈αis␈αa␈αclose␈αrelationship␈αbetween␈αwhat␈αwe
␈↓ ↓H␈↓are␈α∪inducting␈α∪on␈α∪in␈α∪the␈α∩proof␈α∪and␈α∪what␈α∪we␈α∪are␈α∩recurring␈α∪on␈α∪during␈α∪the␈α∪evaluation␈α∪of␈α∩the
␈↓ ↓H␈↓expressions.␈αA␈αprogram␈αwritten␈αby␈αBoyer␈αand␈αMoore␈αhas␈αbeen␈αreasonably␈αsuccessful␈αin␈αgenerating
␈↓ ↓H␈↓proofs like the above by exploiting this relationship. [Boy 75], [Moor 75b]␈↓π 53␈↓.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Prove the associativity of ␈↓αappend␈↓.
␈↓ ↓H␈↓II␈α
Analysis␈αof␈α
the␈αabove␈α
proof␈αshows␈α
frequent␈αuse␈α
of␈αother␈α
results␈αfor␈α
LISP␈αfunctions.␈α
Fill␈α
in␈αthe
␈↓ ↓H␈↓details. Investigate the possibility of formalizing this proof, showing what axioms are needed.
␈↓ ↓H␈↓III Show the equivalence of ␈↓αfact␈↓ (page 42) and ␈↓αfact␈↓β1␈↓ (page 45).
␈↓ ↓H␈↓IV Show the equivalence of ␈↓αlength␈↓ and ␈↓αlength␈↓β1␈↓ (page 45).
␈↓ ↓H␈↓V Using the definition of ␈↓αreverse␈↓, given on page 46, prove:
␈↓ ↓H␈↓␈↓ ¬A␈↓αreverse[reverse[x]] = x␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 53␈↓␈αThere␈αis␈αalso␈αa␈αformal␈αsystem␈αbased␈αon␈αa␈αtyped␈α␈↓λλ␈↓-calculus␈αwhich␈αhas␈αhad␈αsignificant␈αsuccess␈αin
␈↓ ↓H␈↓proving␈α∪properies␈α∪of␈α∩programs.␈α∪ [LCF 72], [New 75].␈α∪More␈α∩recently␈α∪[Car 76]␈α∪has␈α∪developed␈α∩a
␈↓ ↓H␈↓formal␈α∞system␈α∞including␈α
rules␈α∞of␈α∞inference,␈α
a␈α∞proof␈α∞checker,␈α
and␈α∞a␈α∞viable␈α∞programming␈α
language
␈↓ ↓H␈↓which is based on a "typed LISP".
␈↓ ↓H␈↓␈↓↓88 Evaluation␈↓ C3.␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓↓CHAPTER 3
␈↓ ↓H␈↓↓␈↓ ∧6EVALUATION OF LISP EXPRESSIONS␈↓
␈↓ ↓H␈↓␈↓ ∧λ"...␈αI␈αalways␈αworked␈αwith␈αprogramming␈αlanguages␈αbecause␈αit␈αseemed␈αto␈αme
␈↓ ↓H␈↓␈↓ ∧λthat␈α∪until␈α∪you␈α∪could␈α∪understand␈α∪those,␈α∪you␈α∪really␈α∪couldn't␈α∪understand
␈↓ ↓H␈↓␈↓ ∧λcomputers.␈αUnderstanding␈αthem␈αdoesn't␈αreally␈αmean␈αonly␈αbeing␈αable␈αto␈αuse
␈↓ ↓H␈↓␈↓ ∧λthem. A lot of people can use them without understanding them. ..."
␈↓ ↓H␈↓␈↓ λbChristopher Strachey[Str 74]
␈↓ ↓H␈↓␈↓ ¬`␈↓↓3.1 Introduction␈↓
␈↓ ↓H␈↓In␈α
the␈αprevious␈α
chapters␈αof␈α
this␈α
text␈αwe␈α
have␈αtalked␈α
about␈α
some␈αof␈α
the␈αschemes␈α
for␈αevaluation.␈α
We
␈↓ ↓H␈↓have␈α
done␈α
so␈α
rather␈α
informally␈α
for␈α
LISP;␈α∞we␈α
have␈α
been␈α
more␈α
precise␈α
about␈α
evaluation␈α∞of␈α
simple
␈↓ ↓H␈↓arithmetic␈αexpressions.␈αSection 2.6␈αdiscussed␈α
that␈αin␈αsome␈αdetail.␈α We␈α
shall␈αnow␈αlook␈αmore␈αclosely␈α
at
␈↓ ↓H␈↓the␈α∞informal␈α∞process␈α∞which␈α∞we␈α∞have␈α∞been␈α∂using␈α∞in␈α∞the␈α∞evaluation␈α∞of␈α∞LISP␈α∞expressions.␈α∂ This␈α∞is
␈↓ ↓H␈↓motivated by at least two desires.
␈↓ ↓H␈↓We␈α∞want␈α∞to␈α∞run␈α∞our␈α∞LISP␈α∞programs␈α∞on␈α
a␈α∞machine.␈α∞ To␈α∞do␈α∞so␈α∞requires␈α∞the␈α∞implementation␈α∞of␈α
a
␈↓ ↓H␈↓translator␈α∂to␈α∂turn␈α⊂LISP␈α∂programs␈α∂into␈α⊂instructions␈α∂which␈α∂can␈α∂be␈α⊂carried␈α∂out␈α∂by␈α⊂a␈α∂conventional
␈↓ ↓H␈↓machine.␈α We␈α
will␈αbe␈αinterested␈α
in␈αthe␈α
structure␈αof␈αsuch␈α
implementations.␈α Any␈α
implementation␈αof
␈↓ ↓H␈↓LISP␈α∂must␈α∞be␈α∂grounded␈α∂on␈α∞a␈α∂precise,␈α∞and␈α∂clear␈α∂understanding␈α∞of␈α∂what␈α∂LISP-evaluation␈α∞entails.
␈↓ ↓H␈↓Indeed,␈α↔a␈α_deep␈α↔understanding␈α↔of␈α_evaluation␈α↔is␈α↔a␈α_prerequisite␈α↔for␈α↔implementation␈α_of␈α↔␈↓↓any␈↓
␈↓ ↓H␈↓language␈↓π 54␈↓.
␈↓ ↓H␈↓Our␈α∪second␈α∀reason␈α∪for␈α∀pursuing␈α∪evaluation␈α∀involves␈α∪the␈α∀question␈α∪of␈α∀programming␈α∪language
␈↓ ↓H␈↓specification.␈α∞ At␈α∞a␈α∞practical␈α∞level␈α∞we␈α
want␈α∞a␈α∞clean,␈α∞machine␈α∞independent,␈α∞"self-evident"␈α
language
␈↓ ↓H␈↓specification,␈αso␈αthat␈αthe␈αagony␈αinvolved␈αin␈αimplementing␈αthe␈αdesign␈αcan␈αbe␈αminimized.␈α At␈αa␈αmore
␈↓ ↓H␈↓abstract␈αlevel,␈αwe␈αshould␈αtry␈αto␈αunderstand␈αjust␈αwhat␈α␈↓↓is␈↓␈αspecified␈αwhen␈αwe␈αdesign␈αa␈αlanguage.␈αAre
␈↓ ↓H␈↓we␈αspecifying␈α
a␈αsingle␈α
machine,␈αa␈α
class␈αof␈αmachines,␈α
or␈αa␈α
class␈αof␈α
mathematical␈αfunctions?␈αJust␈α
what
␈↓ ↓H␈↓is␈α
a␈α
programming␈αlanguage?␈α
The␈α
syntactic␈α
specification␈αof␈α
languages␈α
is␈α
reasonably␈αwell␈α
established,
␈↓ ↓H␈↓but␈α⊂syntax␈α⊂is␈α⊂only␈α⊂the␈α⊂tip␈α⊂of␈α⊂the␈α⊂iceberg.␈α⊂Our␈α⊂study␈α⊂of␈α⊂LISP␈α⊂will␈α⊂address␈α⊂itself␈α⊂to␈α⊃the␈α⊂deeper
␈↓ ↓H␈↓problems of semantics, or meaning, of languages.
␈↓ ↓H␈↓Before␈αwe␈αaddress␈αthe␈αdirect␈αquestion␈αof␈αLISP␈αevaluation,␈αwe␈αshould␈αperhaps␈αwonder␈αaloud␈αabout
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 54␈↓␈α⊂The␈α⊃question␈α⊂of␈α⊂evaluation␈α⊃cannot␈α⊂be␈α⊂sidestepped␈α⊃by␈α⊂basing␈α⊂a␈α⊃language␈α⊂on␈α⊂a␈α⊃compiler.␈α⊂A
␈↓ ↓H␈↓compiler must produce code which when executed, simulates the evaluation process.
␈↓ ↓H␈↓␈↓↓3.1␈↓ ↑Introduction 89␈↓
␈↓ ↓H␈↓the␈αefficacy␈αof␈αstudying␈αlanguages␈αin␈αthe␈αdetail␈αwhich␈αwe␈αare␈αproposing.␈α As␈αcomputer␈αscientists␈αwe
␈↓ ↓H␈↓should␈αbe␈αcurious␈αabout␈αthe␈αstructure␈αof␈αprogramming␈αlanguages␈αbecause␈αwe␈αmust␈αunderstand␈αour
␈↓ ↓H␈↓tools␈α∞-- our␈α∞programming languages.␈α∂People␈α∞who␈α∞simply␈α∂wish␈α∞to␈α∞␈↓↓use␈↓␈α∂computers␈α∞as␈α∞tools␈α∂need␈α∞not
␈↓ ↓H␈↓care␈α∩about␈α∩the␈α∩structure␈α∩of␈α∩languages.␈α∩Indeed␈α∩they␈α∩usually␈α∩couldn't␈α∩care␈α∩less␈α∩about␈α∩the␈α∩inner
␈↓ ↓H␈↓workings␈α∞of␈α∞the␈α
language;␈α∞they␈α∞only␈α
want␈α∞languages␈α∞in␈α
which␈α∞they␈α∞can␈α
state␈α∞their␈α∞problems␈α∞in␈α
a
␈↓ ↓H␈↓reasonably␈αnatural␈αmanner.␈α They␈αwant␈αtheir␈αprograms␈αto␈αrun␈αand␈αget␈αresults.␈αThey␈αare␈αinterested
␈↓ ↓H␈↓in␈α⊂the␈α⊃output␈α⊂and␈α⊂seldom␈α⊃are␈α⊂interested␈α⊂in␈α⊃the␈α⊂detailed␈α⊂process␈α⊃of␈α⊂computation.␈α⊂ For␈α⊃a␈α⊂simple
␈↓ ↓H␈↓analogy,␈αconsider␈αthe␈αfield␈αof␈αmathematics.␈α The␈αpracticing␈αmathematician␈αuses␈αhis␈αtools␈α
-- proofs --
␈↓ ↓H␈↓in␈α
a␈α
similar␈α
manner␈αto␈α
the␈α
person␈α
interested␈α
in␈αcomputer␈α
applications.␈α
He␈α
seldom␈α
needs␈αto␈α
examine
␈↓ ↓H␈↓questions␈α
like␈α
"what␈α
is␈α∞a␈α
proof?"␈α
He␈α
does␈α∞not␈α
analyze␈α
his␈α
tools.␈α∞ However␈α
not␈α
so␈α
many␈α∞years␈α
ago
␈↓ ↓H␈↓such␈αquestions␈α␈↓↓were␈↓␈αraised,␈αand␈αfor␈αgood␈αreason.␈α Some␈αcommon␈αforms␈αof␈αreasoning␈αwere␈αshown␈α
to
␈↓ ↓H␈↓lead to contradictions unless care was taken.
␈↓ ↓H␈↓Our␈α
position␈α
is␈α
more␈α
like␈α
that␈α
of␈α
the␈α
foundations␈α
of␈α
mathematics;␈α
there␈α
the␈α
tools␈α
of␈α
mathematics␈α
␈↓↓are␈↓
␈↓ ↓H␈↓studied␈αand␈αanalyzed.␈α Mathematics␈αhas␈αflourished␈αbecause␈αof␈αit.␈αThough␈αour␈αexpectations␈αare␈αnot
␈↓ ↓H␈↓quite␈α⊂that␈α⊂presumptuous,␈α⊂we␈α⊃␈↓↓do␈↓␈α⊂expect␈α⊂that␈α⊂programming␈α⊃language␈α⊂design␈α⊂cannot␈α⊂help␈α⊃but␈α⊂be
␈↓ ↓H␈↓improved.
␈↓ ↓H␈↓Our␈α∞study␈α
of␈α∞language␈α
implementation␈α∞will␈α
proceed␈α∞from␈α
the␈α∞abstract␈α
to␈α∞the␈α
concrete.␈α∞Each␈α
level
␈↓ ↓H␈↓will␈α⊃intimately␈α∩involve␈α⊃the␈α∩study␈α⊃of␈α⊃data␈α∩structures.␈α⊃ The␈α∩next␈α⊃two␈α⊃chapters␈α∩will␈α⊃be␈α∩the␈α⊃most
␈↓ ↓H␈↓abstract,␈α∞building␈α∞a␈α∞precise␈α
high-level␈α∞description␈α∞of␈α∞an␈α∞evaluation␈α
scheme␈α∞for␈α∞LISP.␈α∞In␈α∞fact,␈α
the
␈↓ ↓H␈↓discussion␈α
is␈αmuch␈α
more␈αgeneral␈α
than␈αthat␈α
of␈αLISP;␈α
the␈αtext␈α
addresses␈αitself␈α
to␈αproblem␈α
areas␈αin␈α
the
␈↓ ↓H␈↓design␈α⊂of␈α⊂any␈α⊂reasonably␈α⊂sophisticated␈α⊂language.␈α⊂In␈α⊂subsequent␈α⊂chapters␈α⊂we␈α⊂probe␈α⊂beneath␈α⊂the
␈↓ ↓H␈↓surface␈αof␈αthis␈αhigh-level␈αdescription␈αand␈αdiscuss␈αcommon␈αways␈αof␈αimplementing␈αthe␈αnecessary␈αdata
␈↓ ↓H␈↓structures␈αand␈αcontrol␈α
structures.␈α In␈αthe␈αprocess␈α
we␈αwill␈αnot␈αonly␈α
understand␈αLISP␈αbut␈αwill␈α
develop
␈↓ ↓H␈↓a firm understanding of virtually any other language.
␈↓ ↓H␈↓But␈α
how␈α
can␈α
we␈α
begin␈α
to␈α
understand␈α
LISP␈α
evaluation?␈α
In␈α
Section 2.6␈α
we␈α
made␈α
a␈αbeginning,␈α
giving
␈↓ ↓H␈↓an␈αalgorithm␈α
for␈αa␈α
subset␈αof␈αthe␈α
computations␈αexpressible␈α
in␈αLISP.␈α
This␈αsubset␈αcovered␈α
evaluation
␈↓ ↓H␈↓of␈α∩some␈α∩simple␈α∩arithmetic␈α∩expressions.␈α∩ From␈α∩our␈α∩earliest␈α∩grade␈α∩school␈α∩days␈α∩we␈α∩have␈α∩had␈α⊃to
␈↓ ↓H␈↓evaluate␈α⊂simple␈α⊂arithmetic␈α⊃expressions.␈α⊂Later,␈α⊂in␈α⊂algebra␈α⊃we␈α⊂managed␈α⊂to␈α⊂cope␈α⊃with␈α⊂expressions
␈↓ ↓H␈↓involving␈α∀function␈α∀application.␈α∀Most␈α∀of␈α∀us␈α∀survived␈α∀the␈α∀experience.␈α∀We␈α∀should␈α∀now␈α∃try␈α∀to
␈↓ ↓H␈↓understand␈α∞the␈α∞processes␈α∞we␈α
used␈α∞in␈α∞these␈α∞simple␈α∞arithmetic␈α
cases,␈α∞doing␈α∞our␈α∞examination␈α∞at␈α
the
␈↓ ↓H␈↓most␈α∂mechanical␈α∂level.␈α∂ The␈α∂basic␈α∂intent␈α⊂of␈α∂the␈α∂algorithm␈α∂is␈α∂fixed:␈α∂evaluate␈α∂the␈α⊂expression;␈α∂but
␈↓ ↓H␈↓within␈α
that␈α
general␈α
constraint␈αwe␈α
often␈α
have␈α
several␈α
distinct␈αalternatives.␈α
Those␈α
places␈α
at␈αwhich␈α
we
␈↓ ↓H␈↓have␈αchoices␈αshould␈αbe␈αremembered.␈αWe␈αwill␈αmake␈αreasonable␈αchoices␈αso␈αthat␈αthe␈αprocess␈αbecomes
␈↓ ↓H␈↓deterministic␈αand␈αproceed.␈αLater,␈αwe␈αshould␈αreflect␈αon␈αwhat␈αeffect␈αour␈αchoices␈αhad␈αon␈αthe␈αresulting
␈↓ ↓H␈↓scheme.␈α
For␈αexample,␈α
recall␈αthe␈α
discussion␈α
of␈αthe␈α
representation␈αof␈α
symbol␈αtables␈α
on␈α
page 82.␈αWe
␈↓ ↓H␈↓had␈α∂several␈α∂options,␈α⊂but␈α∂picked␈α∂one␈α⊂which␈α∂seemed␈α∂to␈α∂satisfy␈α⊂our␈α∂intuitions␈α∂and␈α⊂was␈α∂reasonably
␈↓ ↓H␈↓efficient.␈α
But␈αwe␈α
should␈αsubject␈α
that␈α
decision␈αto␈α
close␈αscrutiny:␈α
does␈α
it␈αreally␈α
fulfill␈αour␈α
expectations?
␈↓ ↓H␈↓In␈αabsence␈αof␈αabsolute␈αstandards,␈αthese␈αquestions␈αare␈αusually␈αanswered␈αby␈αexamining␈αthe␈αbehavior
␈↓ ↓H␈↓of the algorithm.
␈↓ ↓H␈↓The␈α
first␈α
thing␈α
to␈α
note␈α
in␈α
examining␈α
simple␈α
arithmetic␈α
examples␈α
is␈α
that␈α
␈↓↓nothing␈↓␈α
is␈α
really␈α
said␈α
about
␈↓ ↓H␈↓the␈α∀process␈α∀of␈α∪evaluation.␈α∀ When␈α∀asked␈α∪to␈α∀evaluate␈α∀␈↓α(2*3) + (5*6)␈↓␈α∪we␈α∀never␈α∀specified␈α∪which
␈↓ ↓H␈↓␈↓↓90 Evaluation␈↓ 73.1␈↓
␈↓ ↓H␈↓summand␈α∂was␈α∂to␈α∂be␈α∂evaluated␈α∂first.␈α∂ Indeed␈α∞it␈α∂didn't␈α∂matter␈α∂here.␈α∂␈↓α6 + (5*6)␈↓␈α∂or␈α∂␈↓α(2*3) + 30␈↓␈α∞both
␈↓ ↓H␈↓yield␈α
␈↓α36␈↓.␈α
Does␈α
it␈α␈↓↓ever␈↓␈α
matter?␈α
"+"␈α
and␈α"*"␈α
are␈α
examples␈α
of␈αarithmetic␈α
functions;␈α
can␈α
we␈αalways␈α
leave
␈↓ ↓H␈↓the␈α
order␈α∞of␈α
evaluation␈α∞unspecified␈α
for␈α
arithmetic␈α∞functions?␈α
What␈α∞about␈α
evaluation␈α∞of␈α
arbitrary
␈↓ ↓H␈↓functional␈αexpressions?␈α If␈αthe␈αorder␈αdoesn't␈αmatter,␈αthen␈αthe␈αspecification␈αof␈αthe␈αevaluation␈αprocess
␈↓ ↓H␈↓becomes much simpler. If it ␈↓↓does␈↓ matter then we must know why and where.
␈↓ ↓H␈↓We␈α
have␈α
seen␈α
that␈α
the␈α
order␈α
of␈α
evaluation␈α
␈↓↓can␈↓␈α
make␈α
a␈α
difference␈α
in␈α
LISP.␈α
On␈α
page 15␈α∞we␈α
saw
␈↓ ↓H␈↓that␈α∂␈↓ CBV␈↓,␈α∂LISP's␈α∂computational␈α∂interpretation␈α⊂of␈α∂function␈α∂application,␈α∂requires␈α∂some␈α⊂care.␈α∂ On
␈↓ ↓H␈↓page 20␈α
we␈αsaw␈α
that␈αorder␈α
of␈α
evaluation␈αin␈α
conditional␈αexpressions␈α
can␈α
make␈αa␈α
difference.␈αSince␈α
we
␈↓ ↓H␈↓are␈α
using␈α␈↓ CBV␈↓␈α
we␈αmust␈α
make␈α␈↓↓some␈↓␈α
decision␈α
regarding␈αthe␈α
order␈αof␈α
evaluation␈αof␈α
the␈αarguments␈α
to
␈↓ ↓H␈↓a␈α
function␈αcall,␈α
say␈α
␈↓αf[t␈↓β1␈↓α;t␈↓β2␈↓α;␈α...t␈↓βn␈↓].␈α
We␈α
will␈αassume␈α
that␈α
we␈αwill␈α
evaluate␈α
the␈αarguments␈α
from␈α
left␈αto
␈↓ ↓H␈↓right. This second decision about the order of evaluation can also effect the computation.
␈↓ ↓H␈↓Consider the example due to J. Morris:
␈↓ ↓H␈↓␈↓ ∧N␈↓αf[x;y] <= [x = 0 → 0; ␈↓
t␈↓α → f[x-1;f[y-2;x]]]␈↓.
␈↓ ↓H␈↓Evaluation of ␈↓αf[2;1]␈↓ will terminate if we always evaluate the outermost occurrence of ␈↓αf␈↓. Thus:
␈↓ ↓H␈↓␈↓ ∧9␈↓αf[2;1] = f[1;f[-1;2]] = f[0;f[f[-1;2]-2;1]] = 0;␈↓
␈↓ ↓H␈↓However if we evaluate the innermost occurrences␈↓π 55␈↓ first, the computation will not terminate:
␈↓ ↓H␈↓␈↓ βf␈↓αf[2;1] = f[1;f[-1;2]] = f[1;f[-2;f[0;-1]]] = f[1;f[-2;0]] = ... .␈↓
␈↓ ↓H␈↓The␈α∞choice␈α
of␈α∞evaluation␈α
schemes␈α∞has␈α
far␈α∞reaching␈α
consequences.␈α∞ The␈α
evaluation␈α∞scheme,␈α
␈↓ CBV␈↓,
␈↓ ↓H␈↓which␈αwe␈αchose␈αis␈αcalled␈α␈↓↓call-by-value␈↓.␈α It␈αis␈αcalled␈αapplicative␈αorder␈αevaluation␈αor␈α␈↓↓inside-out␈↓␈αstyle
␈↓ ↓H␈↓of␈αevaluation,␈αmeaning␈αthat␈αwe␈αevaluate␈αthe␈αsubexpressions␈αbefore␈αevaluating␈αthe␈αmain␈αexpression.
␈↓ ↓H␈↓Alternative␈αproposals␈αexist;␈αcall-by-name␈αevaluation,␈αalso␈αcalled␈αnormal␈αorder␈αevaluation,␈αis␈α
another
␈↓ ↓H␈↓common␈αscheme.␈α
We␈αintroduced␈α
this␈αoutside-in␈α
scheme␈αon␈α
page 16␈αas␈α
␈↓ CBN␈↓.␈α From␈αa␈α
computational
␈↓ ↓H␈↓perspective,␈α∞we␈α∞can␈α∞live␈α∂with␈α∞call-by-value,␈α∞though␈α∞we␈α∂know␈α∞the␈α∞use␈α∞of␈α∂such␈α∞a␈α∞rule␈α∞may␈α∂lead␈α∞to
␈↓ ↓H␈↓non-terminating computations when call-by-name would terminate␈↓π 56␈↓.
␈↓ ↓H␈↓Informally,␈α
call-by-value␈α
says:␈αevaluate␈α
the␈α
arguments␈αto␈α
a␈α
function␈αbefore␈α
you␈α
apply␈α
the␈αfunction
␈↓ ↓H␈↓definition␈α∞to␈α∞the␈α
arguments.␈α∞ Let's␈α∞look␈α∞at␈α
a␈α∞simple␈α∞arithmetic␈α∞example.␈α
Let␈α∞␈↓αf[x;y]␈↓␈α∞be␈α∞␈↓αx␈↓π2␈↓α + y␈↓␈α
and
␈↓ ↓H␈↓consider␈α⊂␈↓αf[3+4;2*2]␈↓.␈α⊂ Then␈α∂call-by-value␈α⊂says␈α⊂evaluate␈α∂the␈α⊂arguments,␈α⊂getting␈α∂␈↓α7␈↓␈α⊂and␈α⊂␈↓α4␈↓;␈α∂associate
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 55␈↓␈α⊂The␈α⊃notions␈α⊂of␈α⊃"innermost"␈α⊂and␈α⊃"outermost"␈α⊂evaluation␈α⊃need␈α⊂to␈α⊃be␈α⊂slightly␈α⊃embellished␈α⊂for
␈↓ ↓H␈↓multiple-argument␈α⊃applications.␈α⊃If␈α⊃the␈α⊃chosen␈α⊂application␈α⊃has␈α⊃several␈α⊃arguments,␈α⊃then␈α⊃we␈α⊂must
␈↓ ↓H␈↓specify␈α%an␈α%order␈α%for␈α%their␈α%evaluation.␈α% Thus␈α%terms␈α%like␈α%"leftmost-outermost"␈α$and
␈↓ ↓H␈↓"rightmost-innermost"␈α
occur.␈α
For␈α∞example,␈α
the␈α
LISP␈α
scheme␈α∞is␈α
an␈α
instance␈α∞of␈α
"leftmost-innermost"
␈↓ ↓H␈↓evaluation.
␈↓ ↓H␈↓␈↓π 56␈↓␈α∩There␈α∩are␈α⊃also␈α∩examples␈α∩where␈α⊃call-by-value␈α∩will␈α∩terminate␈α⊃but␈α∩call-by-name␈α∩will␈α∩not.␈α⊃See
␈↓ ↓H␈↓page 213.
␈↓ ↓H␈↓␈↓↓3.1␈↓ ↑Introduction 91␈↓
␈↓ ↓H␈↓those␈α
values␈α
with␈α
the␈α
formal␈α
parameters␈α
of␈α
␈↓αf␈↓␈α
(i.e.␈α
␈↓α7␈↓␈α
with␈α
␈↓αx␈↓␈α
and␈α
␈↓α4␈↓␈α
with␈α
␈↓αy␈↓)␈α
and␈α
then␈α
evaluate␈α
the␈α
body
␈↓ ↓H␈↓of ␈↓αf␈↓ resulting in ␈↓α7␈↓π2␈↓α + 4 = 53␈↓. This is the scheme we captured in Section 2.6.
␈↓ ↓H␈↓Call-by-name␈α⊂says␈α⊂pass␈α⊂the␈α⊂␈↓↓unevaluated␈↓␈α⊂actual␈α⊂parameters␈α⊂to␈α⊂the␈α⊂function,␈α⊃giving␈α⊂␈↓α(3+4)␈↓π2␈↓α + 2*2␈↓,
␈↓ ↓H␈↓which␈α
also␈α
evaluates␈α
to␈α
␈↓α53␈↓.␈α
Evaluation␈α
can␈α
be␈α
described␈α
as␈α
"substitution␈α
followed␈αby␈α
simplification";
␈↓ ↓H␈↓the␈α∃different␈α⊗evaluation␈α∃schemes␈α⊗involve␈α∃different␈α∃choices␈α⊗about␈α∃the␈α⊗order␈α∃in␈α⊗which␈α∃those
␈↓ ↓H␈↓operations␈α
are␈αperformed.␈α
We␈αwill␈α
say␈α
more␈αabout␈α
call-by-name␈αand␈α
other␈αstyles␈α
of␈α
evaluation␈αin
␈↓ ↓H␈↓Section 3.13 and Section 4.9. Most of this chapter will be restricted to call-by-value.
␈↓ ↓H␈↓If␈α∂you␈α∂look␈α∂at␈α∂the␈α∂structure␈α∂of␈α∂␈↓αvalue␈↓λ''␈↓␈α∂and␈α∂␈↓αapply␈↓λ'␈↓␈α∂beginning␈α∂on␈α∂page 80␈α∂you␈α∂will␈α∂see␈α∂that␈α∂they
␈↓ ↓H␈↓encode the call-by-value strategy and have the followng interpretation:
␈↓ ↓H␈↓␈↓↓1.␈↓␈αIf␈αthe␈α
expression␈αis␈αa␈α
constant␈αthen␈αthe␈α
value␈αof␈αthe␈α
expression␈αis␈αthat␈α
constant.␈α (The␈αvalue␈αof␈α
␈↓α3␈↓
␈↓ ↓H␈↓is ␈↓α3␈↓ ␈↓π 57␈↓).
␈↓ ↓H␈↓␈↓↓2.␈↓␈αIf␈α
the␈αexpression␈α
is␈αa␈αvariable␈α
then␈αsee␈α
what␈αthe␈αcurrent␈α
value␈αassociated␈α
with␈αthat␈α
variable␈αis.
␈↓ ↓H␈↓Within the evaluation of, say, ␈↓αf[3;4]␈↓ where ␈↓αf[x;y] <= x␈↓π2␈↓α + y ␈↓the current value of the variable ␈↓αx␈↓ is ␈↓α3␈↓.
␈↓ ↓H␈↓␈↓↓3.␈↓␈αThe␈αonly␈αother␈α
kind␈αof␈αarithmetic␈αexpression␈α
that␈αwe␈αcan␈αhave␈α
is␈αa␈αfunction␈αname␈α
followed␈αby
␈↓ ↓H␈↓arguments,␈αfor␈αexample␈α␈↓αf[3;4]␈↓.␈α In␈αthis␈αcase␈αwe␈αfirst␈αevaluate␈αthe␈αarguments␈α␈↓π 58␈↓␈αand␈αthen␈αapply␈αthe
␈↓ ↓H␈↓definition␈αof␈αthe␈αfunction␈αto␈αthose␈αevaluated␈αarguments.␈α When␈αwe␈αapply␈αthe␈αfunction␈αdefinition␈α
to
␈↓ ↓H␈↓the␈α
evaluated␈α
arguments␈α
we␈αassociate␈α
the␈α
formal␈α
parameters␈α
of␈αthe␈α
definition␈α
with␈α
the␈α
values␈αof␈α
the
␈↓ ↓H␈↓actual␈α∂parameters.␈α∂ This␈α∂process␈α∂of␈α∂associating␈α∞parameters␈α∂is␈α∂called␈α∂␈↓↓binding␈↓␈α∂and␈α∂simulates␈α∞some
␈↓ ↓H␈↓form␈α⊂of␈α⊂substitution.␈α⊂ We␈α⊂then␈α⊂evaluate␈α⊂the␈α∂body␈α⊂of␈α⊂the␈α⊂function␈α⊂using␈α⊂this␈α⊂new␈α∂environment.
␈↓ ↓H␈↓Notice␈α∩that␈α∩we␈α∪do␈α∩␈↓↓not␈↓␈α∩explicitly␈α∩substitute␈α∪the␈α∩values␈α∩for␈α∩the␈α∪variables␈α∩which␈α∩appear␈α∪in␈α∩an
␈↓ ↓H␈↓expression. We ␈↓↓simulate␈↓ substitutions by table lookup.
␈↓ ↓H␈↓We␈α
want␈α
to␈α∞apply␈α
this␈α
treatment␈α
of␈α∞evaluation␈α
to␈α
LISP␈α
expressions.␈α∞ If␈α
the␈α
LISP␈α
expression␈α∞is␈α
a
␈↓ ↓H␈↓constant,␈αthen␈αthe␈αvalue␈αof␈αthe␈αexpression␈αis␈αthat␈αconstant.␈α The␈αconstants␈αof␈αLISP␈αare␈αthe␈αS-exprs.
␈↓ ↓H␈↓Thus␈α⊃the␈α⊂value␈α⊃of␈α⊃␈↓α(A . B)␈↓␈α⊂is␈α⊃␈↓α(A . B)␈↓,␈α⊃just␈α⊂like␈α⊃the␈α⊃value␈α⊂of␈α⊃␈↓α3␈↓␈α⊃is␈α⊂␈↓α3␈↓.␈α⊃ Variables␈α⊃and␈α⊂functional
␈↓ ↓H␈↓applications␈αappear␈αin␈α
LISP␈αand␈αare␈αhandled␈α
similarly␈αto␈α␈↓↓2␈↓␈αand␈α
␈↓↓3␈↓␈αabove.␈α The␈α
additional␈αartifact
␈↓ ↓H␈↓of␈αLISP␈αis␈αthe␈αconditional␈αexpression.␈αBut␈αits␈αevaluation␈αcan␈αalso␈αbe␈αprecisely␈αspecified.␈αWe␈αdid␈αso
␈↓ ↓H␈↓on page 19.
␈↓ ↓H␈↓In more specific detail, here is some of the structure of the LISP evaluation mechanism:
␈↓ ↓H␈↓␈↓↓1.␈↓ If the expression to be evaluated is a constant then the value is that constant.
␈↓ ↓H␈↓␈↓↓2.␈↓ If the expression is a variable find its value in the current environment.
␈↓ ↓H␈↓␈↓↓3.␈↓␈αIf␈αthe␈αexpression␈αis␈αa␈αconditional␈αexpression␈αthen␈αit␈αis␈αof␈αthe␈αform␈α␈↓α[p␈↓β1␈↓α → e␈↓β1␈↓α; p␈↓β2␈↓α → e␈↓β2␈↓α; ... ;p␈↓βn␈↓α → e␈↓βn␈↓].
␈↓ ↓H␈↓Evaluate it using the semantics defined on page 19.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 57␈↓ We are ignoring the distinction between the ␈↓↓numeral␈↓ ␈↓α3␈↓ and the ␈↓↓number␈↓α 3.␈↓
␈↓ ↓H␈↓␈↓π 58␈↓ Here we are using the evaluation process recursively.
␈↓ ↓H␈↓␈↓↓92 Evaluation␈↓ 73.1␈↓
␈↓ ↓H␈↓␈↓↓4.␈↓ If the expression is of the form: ␈↓αf␈↓[␈↓αt␈↓β1␈↓α;t␈↓β2␈↓α; ... ;t␈↓βn␈↓α]␈↓ then:
␈↓ ↓H␈↓␈↓ αh␈↓↓a.␈↓ Evaluate the arguments ␈↓αt␈↓β1␈↓α, t␈↓β2␈↓α, ... ,t␈↓βn␈↓ from left to right.
␈↓ ↓H␈↓␈↓ αh␈↓↓b.␈↓ Find the definition of the function, ␈↓αf␈↓.
␈↓ ↓H␈↓␈↓ αh␈↓↓c.␈↓␈α∂Associate␈α∂the␈α∂evaluated␈α∂arguments␈α∂with␈α∂the␈α∂formal␈α∂parameters␈α∂in␈α∂the
␈↓ ↓H␈↓␈↓ αhfunction definition.
␈↓ ↓H␈↓␈↓ αh␈↓↓d.␈↓␈αEvaluate␈αthe␈αbody␈αof␈αthe␈αfunction,␈αwhile␈αremembering␈αthe␈αvalues␈αof␈αthe
␈↓ ↓H␈↓␈↓ αhvariables.
␈↓ ↓H␈↓We␈α⊂saw␈α⊂in␈α⊂(Section 2.6)␈α⊂that␈α⊂a␈α⊂simple␈α⊃kind␈α⊂of␈α⊂arithmetic␈α⊂evaluation␈α⊂can␈α⊂be␈α⊂transcribed␈α⊃into␈α⊂a
␈↓ ↓H␈↓recursive␈α⊂LISP␈α⊃algorithm.␈α⊂ That␈α⊃algorithm␈α⊂operates␈α⊂on␈α⊃a␈α⊂representation␈α⊃of␈α⊂the␈α⊃expression␈α⊂and
␈↓ ↓H␈↓produces␈αthe␈αvalue.␈αMost␈αof␈αour␈αwork␈αin␈αthat␈αexample␈αwas␈αdone␈αwithout␈αgiving␈αexplicit␈α
details␈αof
␈↓ ↓H␈↓the representation. We had previously given a detailed representation in Section 2.3.
␈↓ ↓H␈↓We␈α∩have␈α∩demonstrated␈α∩an␈α⊃informal,␈α∩but␈α∩reasonably␈α∩precise,␈α⊃evaluation␈α∩scheme␈α∩for␈α∩LISP;␈α⊃our
␈↓ ↓H␈↓discussion␈α
is␈α
ready␈α∞for␈α
more␈α
formal␈α∞development.␈α
It␈α
should␈α∞be␈α
clear␈α
that␈α∞we␈α
could␈α
write␈α∞a␈α
LISP
␈↓ ↓H␈↓function␈αrepresenting␈α
the␈αevaluation␈α
process␈αprovided␈α
that␈αwe␈α
can␈αfind␈α
a␈αrepresentation␈α
for␈αLISP
␈↓ ↓H␈↓expressions␈αas␈αS-expressions.␈αThis␈αmapping,␈α␈↓
R␈↓,␈αof␈α
LISP␈αexpressions␈αto␈αS-exprs␈αis␈αour␈αfirst␈αorder␈α
of
␈↓ ↓H␈↓business.␈α⊂We␈α∂will␈α⊂accomplish␈α∂this␈α⊂mapping␈α⊂by␈α∂using␈α⊂an␈α∂extension␈α⊂of␈α∂the␈α⊂scheme␈α⊂introduced␈α∂in
␈↓ ↓H␈↓Section 2.3.
␈↓ ↓H␈↓The␈α∂idea␈α∞of␈α∂mapping␈α∞LISP␈α∂expressions␈α∞onto␈α∂S-exprs␈α∂and␈α∞writing␈α∂a␈α∞LISP␈α∂function␈α∞to␈α∂act␈α∂as␈α∞an
␈↓ ↓H␈↓evaluator␈α∩may␈α∩seem␈α∩a␈α∩bit␈α∩incestuous,␈α∩but␈α∩the␈α∩mapping␈α∩is␈α∩no␈α∩more␈α∩obscure␈α∩than␈α∩that␈α∩in␈α∩the
␈↓ ↓H␈↓polynomial␈α∞evaluation␈α∞or␈α∞differentiation␈α∞examples.␈α∞ It␈α∞is␈α∞just␈α∞another␈α∞instance␈α∞of␈α∞the␈α∂diagram␈α∞of
␈↓ ↓H␈↓page 52,␈αonly␈αnow␈αwe␈αare␈αapplying␈αthe␈αprocess␈αto␈αLISP␈αitself.␈α Once␈αthe␈αrepresentation␈αis␈αgiven␈αwe
␈↓ ↓H␈↓will␈αproduce␈αa␈αLISP␈αalgorithm␈αwhich␈αdescribes␈αthe␈αevaluation␈αprocess␈αused␈αin␈αLISP.␈α The␈αeffect␈αis
␈↓ ↓H␈↓to␈α∞force␈α∞us␈α∂to␈α∞make␈α∞precise␈α∞exactly␈α∂what␈α∞is␈α∞meant␈α∞by␈α∂LISP␈α∞evaluation.␈α∞This␈α∞precision␈α∂will␈α∞have
␈↓ ↓H␈↓many important ramifications.
␈↓ ↓H␈↓In terms of the diagrams on page 52 we have:
␈↓ ↓H␈↓LISP evaluation => LISP evaluation algorithm
␈↓ ↓H␈↓ Call-by-value ␈↓αeval␈↓␈↓ ¬h|
␈↓ ↓H␈↓␈↓ ¬h| LISP evaluation
␈↓ ↓H␈↓␈↓ ¬h|=====> ␈↓
R␈↓∞(␈↓αA␈↓∞)␈↓ interpret S-expr output as answer ␈↓αA␈↓.
␈↓ ↓H␈↓␈↓ ¬h|
␈↓ ↓H␈↓LISP expression => Representation␈↓ ¬h|
␈↓ ↓H␈↓ ␈↓αcar[(A . B)] ␈↓
R␈↓∞(␈↓αcar[(A . B)]␈↓∞)␈↓α␈↓ ¬h|
␈↓ ↓H␈↓␈↓↓3.1␈↓ ↑Introduction 93␈↓
␈↓ ↓H␈↓The␈α
diagram␈α
is␈α
␈↓↓almost␈↓␈α
circular.␈α
We␈α
evaluate␈α
an␈α
evaluation␈α
algorithm␈α
named␈α
␈↓αeval␈↓.␈α
We␈α
break␈αthe
␈↓ ↓H␈↓circle␈αby␈αsupplying␈αa␈αlower-level␈αimplementation␈αof␈αthe␈αoriginal␈αevaluator.␈αThat␈αwill␈αbe␈αthe␈αsubject
␈↓ ↓H␈↓of Chapter 5 and Chapter 6. With that, our diagram reduces to:
␈↓ ↓H␈↓LISP expression =>␈↓ βXRepresentation =LISP evaluation=>␈↓ πhRepresentation of answer.
␈↓ ↓H␈↓ ␈↓αcar[(A . B)]␈↓ βX ␈↓
R␈↓∞(␈↓αcar[(A . B)]␈↓∞)␈↓␈↓ ¬H ␈↓αeval␈↓␈↓ πh ␈↓
R␈↓∞(␈↓αA␈↓∞)␈↓.
␈↓ ↓H␈↓This␈α
picture␈α
reflects␈α
two␈α
points:␈α
we␈α
should␈α
pick␈α
a␈α
representation␈α
such␈α
that␈α
the␈α
reinterpretation␈αof
␈↓ ↓H␈↓the␈α⊃answer␈α∩is␈α⊃easy.␈α∩We␈α⊃should␈α⊃also␈α∩pick␈α⊃a␈α∩representation␈α⊃such␈α⊃that␈α∩the␈α⊃representation␈α∩of␈α⊃the
␈↓ ↓H␈↓expression␈α
is␈α
easy.␈α
If␈α
those␈α
two␈α
conditions␈α
are␈α
satisfied,␈α
then␈α
we␈α
might␈α
as␈α
well␈α
write␈α
our␈α
programs␈α
in
␈↓ ↓H␈↓the␈α
representation␈α
and␈α
do␈α∞the␈α
input␈α
and␈α
output␈α
transformations␈α∞ourselves.␈α
With␈α
this␈α
in␈α∞mind␈α
we
␈↓ ↓H␈↓can simplify further to:
␈↓ ↓H␈↓␈↓ β3␈↓
R␈↓∞(␈↓αcar[(A . B)]␈↓∞)␈↓ ==a LISP evaluation algorithm=> ␈↓
R␈↓∞(␈↓αA␈↓∞)␈↓.
␈↓ ↓H␈↓This␈α∂last␈α∞diagram␈α∂reflects␈α∞the␈α∂typical␈α∞LISP␈α∂programming␈α∞language.␈α∂We␈α∞program␈α∂using␈α∂the␈α∞data
␈↓ ↓H␈↓structure representation.
␈↓ ↓H␈↓We've␈α
already␈α
seen␈α
the␈α∞evaluation␈α
of␈α
representations␈α
of␈α∞LISP␈α
expressions.␈α
The␈α
␈↓↓great␈α∞mother␈α
of
␈↓ ↓H␈↓↓all␈αfunctions␈↓␈αis␈αexactly␈αthe␈αevaluation␈αmechanism␈αfor␈αthe␈αLISP␈αprimitive␈αfunctions␈αand␈α
predicates,
␈↓ ↓H␈↓␈↓αcar,␈αcdr,␈αcons,␈αatom␈↓␈αand␈α␈↓αeq␈↓␈αwhen␈αrestricted␈αto␈αfunctional␈αcomposition␈αand␈αconstant␈αarguments.␈α The
␈↓ ↓H␈↓␈↓↓great␈α
mother␈α
revisited␈↓␈αis␈α
the␈α
extension␈αto␈α
conditional␈α
expressions.␈α The␈α
representation␈α
used␈αthere
␈↓ ↓H␈↓was a list representation, and exemplifies a notation which we will develop further.
␈↓ ↓H␈↓In␈α
the␈αnext␈α
section␈α
we␈αwill␈α
give␈α
a␈αspecific␈α
mapping␈α
of␈αLISP␈α
expressions␈α
onto␈αlists␈α
and␈αS-exprs.␈α
But
␈↓ ↓H␈↓remember␈αthat␈αwe␈αshould␈αattempt␈αto␈αkeep␈αthe␈αknowledge␈αof␈αthe␈αrepresentation␈αout␈αof␈αthe␈αstructure
␈↓ ↓H␈↓of␈α∀the␈α∀algorithm.␈α∀ Let's␈α∀stop␈α∀for␈α∀a␈α∀description␈α∀of␈α∀the␈α∀representation␈α∀and␈α∀some␈α∀examples␈α∀of
␈↓ ↓H␈↓translating LISP functions into that representation.
␈↓ ↓H␈↓␈↓ ∧%␈↓↓3.2 S-expr Translation of LISP Expressions␈↓
␈↓ ↓H␈↓We␈α
will␈α
go␈αthrough␈α
the␈α
list␈αof␈α
LISP␈α
constructs,␈αdescribing␈α
the␈α
effect␈αof␈α
the␈α
representational␈αmap,␈α
␈↓
R␈↓,
␈↓ ↓H␈↓and give a few examples applying ␈↓
R␈↓.
␈↓ ↓H␈↓␈↓↓94 Evaluation␈↓ 53.2␈↓
␈↓ ↓H␈↓We will represent numerals just as numerals, e.g.:
␈↓ ↓H␈↓␈↓ ¬
␈↓
R␈↓∞( ␈↓<numeral> ␈↓∞)␈↓α = ␈↓<numeral>
␈↓ ↓H␈↓␈↓ εβ␈↓
R␈↓∞( ␈↓α2 ␈↓∞)␈↓α = 2
␈↓ ↓H␈↓We will translate identifiers to their upper-case counterpart. Thus:
␈↓ ↓H␈↓␈↓ ∧o␈↓
R␈↓∞( ␈↓<identifier> ␈↓∞)␈↓α = ␈↓<literal atom>
␈↓ ↓H␈↓␈↓ ε↓␈↓
R␈↓∞( ␈↓αx ␈↓∞)␈↓α = X
␈↓ ↓H␈↓α␈↓ ¬s␈↓
R␈↓∞( ␈↓αy2 ␈↓∞)␈↓α = Y2
␈↓ ↓H␈↓α␈↓ ¬b␈↓
R␈↓∞( ␈↓αcar ␈↓∞)␈↓α = CAR
␈↓ ↓H␈↓Now␈αwe've␈αgot␈αa␈αproblem:␈αWe␈αwish␈αto␈αmap␈αarbitrary␈αLISP␈αexpressions␈αto␈αS-expressions.␈αThe␈α
LISP
␈↓ ↓H␈↓expression␈α∩␈↓αx␈↓␈α⊃translates␈α∩to␈α⊃␈↓αX␈↓.␈α∩␈↓αX␈↓␈α⊃is␈α∩itself␈α⊃a␈α∩LISP␈α⊃expression␈α∩(a␈α⊃constant);␈α∩␈↓↓it␈↓␈α⊃must␈α∩also␈α∩have␈α⊃a
␈↓ ↓H␈↓translation.␈α We␈αmust␈αbe␈αa␈αlittle␈αcareful␈αhere.␈αWhen␈αwe␈αwrite␈αSon␈αof␈αGreat␈αMother␈αwe␈αwill␈αgive␈αit
␈↓ ↓H␈↓an␈α
S-expr␈α
representation␈α
of␈α
a␈α
form␈α
to␈α
be␈αevaluated.␈α
We␈α
might␈α
give␈α
it␈α
the␈α
representation␈α
of␈α␈↓αcar[x]␈↓␈α
in
␈↓ ↓H␈↓which␈αcase␈αthe␈αvalue␈αcomputed␈αwill␈αdepend␈αon␈αthe␈αcurrent␈αvalue␈αbound␈αto␈α␈↓αx␈↓.␈α We␈αmight␈αalso␈αgive
␈↓ ↓H␈↓the␈α∂representation␈α∂of␈α∂␈↓αcar[X]␈↓;␈α∂in␈α∂this␈α∂case␈α∂we␈α∂should␈α∂expect␈α∂to␈α∂be␈α∂presented␈α∂with␈α∂␈↓λB␈↓␈α∂or␈α⊂an␈α∂error
␈↓ ↓H␈↓message.␈α
Or,␈αfor␈α
example,␈αsome␈α
function␈α
␈↓αfoo␈↓␈αwe␈α
wish␈αto␈α
write␈α
may␈αreturn␈α
the␈αS-expr␈α
representation
␈↓ ↓H␈↓of␈αa␈αLISP␈αform␈αas␈αits␈αvalue.␈α Say␈α␈↓αfoo[1]␈↓␈αreturns␈αthe␈αrepresentation␈αof␈α␈↓αcar[x]␈↓␈αand␈α␈↓αfoo[2]␈↓␈α
returns␈αthe
␈↓ ↓H␈↓representation␈α∞of␈α∞␈↓αcar[X]␈↓.␈α∞We␈α∞must␈α∞be␈α
able␈α∞to␈α∞distinguish␈α∞between␈α∞these␈α∞representations.␈α∞ That␈α
is,
␈↓ ↓H␈↓given␈αthe␈α
representation,␈αthere␈α
should␈αbe␈α
exactly␈αone␈α
way␈αof␈α
interpreting␈αit␈α
as␈αa␈α
LISP␈αexpression.
␈↓ ↓H␈↓The␈α
mapping␈α
must␈α
be␈α
1-1.␈α∞So␈α
we␈α
must␈α
represent␈α
␈↓αx␈↓␈α∞and␈α
␈↓αX␈↓␈α
as␈α
␈↓↓different␈↓␈α
S-exprs.␈α∞ The␈α
translation
␈↓ ↓H␈↓scheme we pick is: for any S-expression ␈↓λα␈↓, its translation is ␈↓α(QUOTE ␈↓λα␈↓α)␈↓.
␈↓ ↓H␈↓␈↓ ∧j␈↓
R␈↓∞( ␈↓<sexpr> ␈↓∞)␈↓α = (QUOTE ␈↓<sexpr>␈↓α)␈↓
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓␈↓ ¬9␈↓
R␈↓∞( ␈↓αX ␈↓∞)␈↓α = (QUOTE X)␈↓
␈↓ ↓H␈↓␈↓ ∧x␈↓
R␈↓∞( ␈↓α(A . B) ␈↓∞)␈↓α = (QUOTE (A . B))␈↓
␈↓ ↓H␈↓␈↓ ∧i␈↓
R␈↓∞( ␈↓αQUOTE ␈↓∞)␈↓α = (QUOTE QUOTE)␈↓
␈↓ ↓H␈↓We␈α⊃must␈α⊂also␈α⊃show␈α⊂how␈α⊃to␈α⊂map␈α⊃expressions␈α⊂of␈α⊃the␈α⊂form␈α⊃␈↓αf[e␈↓β1␈↓α ; ... ;e␈↓βn␈↓α]␈↓␈α⊂onto␈α⊃S-exprs.␈α⊃ We␈α⊂have
␈↓ ↓H␈↓already␈αseen␈αone␈α
satisfactory␈αmapping␈αfor␈αfunctions␈α
in␈αprefix␈αform␈αin␈α
Section 2.3.␈α We␈αwill␈αuse␈α
that
␈↓ ↓H␈↓mapping, called Cambridge Polish␈↓π 59␈↓, here. That is:
␈↓ ↓H␈↓␈↓ β3␈↓
R␈↓∞( ␈↓αf[e␈↓β1␈↓α;e␈↓β2␈↓α; ...;e␈↓βn␈↓α] ␈↓∞)␈↓α = ( ␈↓
R␈↓∞( ␈↓αf ␈↓∞)␈↓α ␈↓
R␈↓∞(␈↓α e␈↓β1␈↓α ␈↓∞)␈↓α ␈↓
R␈↓∞(␈↓α e␈↓β2␈↓α ␈↓∞)␈↓α ... ␈↓
R␈↓∞(␈↓α e␈↓βn␈↓α ␈↓∞)␈↓α )␈↓
␈↓ ↓H␈↓Examples:␈↓α
␈↓ ↓H␈↓α␈↓ ∧ ␈↓
R␈↓∞( ␈↓αcar[x] ␈↓∞)␈↓α = (␈↓
R␈↓∞( ␈↓αcar ␈↓∞)␈↓α ␈↓
R␈↓∞( ␈↓αx ␈↓∞)␈↓α ) = (CAR X)
␈↓ ↓H␈↓α␈↓ βU␈↓
R␈↓∞( ␈↓αcar[X] ␈↓∞)␈↓α = (␈↓
R␈↓∞( ␈↓αcar ␈↓∞)␈↓α ␈↓
R␈↓∞( ␈↓αX ␈↓∞)␈↓α ) = (CAR (QUOTE X))
␈↓ ↓H␈↓α␈↓ β+␈↓
R␈↓∞( ␈↓αcons[cdr[(A . B)];x] ␈↓∞)␈↓α = (CONS (CDR (QUOTE (A . B))) X)
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 59␈↓␈α⊃The␈α⊃name,␈α⊃Cambridge␈α∩Polish,␈α⊃is␈α⊃derived␈α⊃from␈α⊃two␈α∩sources:␈α⊃Cambridge,␈α⊃since␈α⊃M.I.T.␈α∩is␈α⊃in
␈↓ ↓H␈↓Cambridge␈α∞Massachusetts,␈α∞and␈α∞McCarthy␈α
was␈α∞at␈α∞M.I.T.␈α∞while␈α
developing␈α∞his␈α∞ideas;␈α∞Polish,␈α
since
␈↓ ↓H␈↓the representation is a dialect of a notation developed by a school of Polish logicians.
␈↓ ↓H␈↓␈↓↓3.2␈↓ εiS-expr Translation of LISP Expressions 95␈↓
␈↓ ↓H␈↓α␈↓The␈α␈↓
R␈↓-mapping␈αmust␈α
handle␈αconditional␈αexpressions.␈α
A␈αconditional␈αis␈α
represented␈αas␈αa␈α
list␈αwhose
␈↓ ↓H␈↓first␈αelement␈α
is␈α␈↓αCOND␈↓␈α
and␈αwhose␈α
next␈α␈↓αn␈↓␈α
elements␈αare␈α
representations␈αof␈α
the␈α␈↓αp␈↓βi␈↓α-e␈↓βi␈↓␈α
pairs.␈αThe␈α
␈↓
R␈↓-map
␈↓ ↓H␈↓of such pairs is a list of the ␈↓
R␈↓-maps of the two elements:
␈↓ ↓H␈↓␈↓ α3␈↓
R␈↓∞( ␈↓α[p␈↓β1␈↓α → e␈↓β1␈↓α; ... ;p␈↓βn␈↓α → e␈↓βn␈↓α] ␈↓∞)␈↓α = (COND (␈↓
R␈↓∞(␈↓α p␈↓β1 ␈↓∞)␈↓α ␈↓
R␈↓∞(␈↓α e␈↓β1␈↓∞)␈↓α ) ... (␈↓
R␈↓∞(␈↓α p␈↓βn␈↓α ␈↓∞)␈↓α ␈↓
R␈↓∞(␈↓α e␈↓βn ␈↓∞)␈↓α))
␈↓ ↓H␈↓α␈↓An example:␈↓α
␈↓ ↓H␈↓α␈↓ αd␈↓
R␈↓∞( ␈↓α[atom[x] →1; q[y] → X] ␈↓∞)␈↓α = (COND ((ATOM X) 1) ((Q Y) (QUOTE X)))
␈↓ ↓H␈↓Notice␈αthat␈α
␈↓α(COND ... )␈↓␈αand␈α
␈↓α(QUOTE ... )␈↓␈α␈↓↓look␈↓␈α
like␈αtranslations␈α
of␈αfunction␈α
applications␈αof␈αthe␈α
form
␈↓ ↓H␈↓␈↓αcond[ ... ]␈α␈↓␈αand␈α␈↓αquote[ ... ]␈↓.␈αHowever␈αsince␈αwe␈αexpect␈αapplication␈αto␈αbe␈αperformed␈αusing␈αcall-by-value,
␈↓ ↓H␈↓we␈αmust␈αhandle␈αthese␈αconstructs␈αin␈αa␈αspecial␈αmanner.␈α Indeed,␈α␈↓αquote[␈↓λα␈↓α]␈↓␈αstands␈αfor␈α␈↓
R␈↓∞(␈↓λα␈↓∞)␈↓,␈αand␈αthat
␈↓ ↓H␈↓the␈α∪"arguments"␈α∪to␈α∪␈↓αcond␈↓␈α∪are␈α∪not␈α∀to␈α∪be␈α∪interpreted␈α∪as␈α∪in␈α∪function␈α∪applications.␈α∀For␈α∪example,
␈↓ ↓H␈↓␈↓αCOND ((ATOM X) 1) ...)␈↓ doesn't represent ␈↓αcond[ atom[x][1]; ... ]␈↓.
␈↓ ↓H␈↓Finally, the translations of the truth values ␈↓
t␈↓ and ␈↓
f␈↓ will be ␈↓αT␈↓ and ␈↓αNIL␈↓, respectively.
␈↓ ↓H␈↓␈↓ ε ␈↓
R␈↓∞( ␈↓
t␈↓∞ )␈↓α = T
␈↓ ↓H␈↓α␈↓ ¬v␈↓
R␈↓∞( ␈↓
f␈↓∞ )␈↓α = NIL
␈↓ ↓H␈↓You␈α
might␈α∞have␈α
noticed␈α∞that␈α
these␈α∞last␈α
two␈α∞applications␈α
of␈α∞the␈α
␈↓
R␈↓-mapping␈α∞have␈α
the␈α∞potential␈α
to
␈↓ ↓H␈↓cause trouble. They will spoil the 1-1 property of ␈↓
R␈↓:
␈↓ ↓H␈↓␈↓ ε
␈↓
R␈↓∞( ␈↓αt␈↓∞ )␈↓α = T
␈↓ ↓H␈↓α␈↓ ¬j␈↓
R␈↓∞( ␈↓αnil␈↓∞ )␈↓α = NIL
␈↓ ↓H␈↓The usual way to escape from this difficulty is to outlaw ␈↓αt␈↓ and ␈↓αnil␈↓ as LISP variables␈↓π 60␈↓.
␈↓ ↓H␈↓Perhaps␈α∀our␈α∀concern␈α∀for␈α∀the␈α∀␈↓
R␈↓-mapping's␈α∀properties␈α∀appears␈α∀heavy-handed␈α∀where␈α∀a␈α∀simple
␈↓ ↓H␈↓solution␈α
seems␈αapparent:␈α
␈↓
t␈↓␈αis␈α
␈↓
t␈↓␈α
and␈α␈↓αt␈↓␈α
is␈α␈↓αt␈↓;␈α
when␈αwe␈α
want␈α
the␈αtruth␈α
value␈αwe␈α
write␈α␈↓
t␈↓␈α
and␈α
when␈αwe
␈↓ ↓H␈↓want␈α
the␈α
variable␈α
we␈α
write␈α
␈↓αt␈↓.␈α
The␈α
problem␈α
is␈α
that␈α
when␈α
we␈α
write␈α
programs␈α
in␈α
a␈α
format␈α∞which␈α
a
␈↓ ↓H␈↓machine␈α
version␈α
of␈α∞LISP␈α
will␈α
understand,␈α
we␈α∞will␈α
be␈α
writing␈α
the␈α∞␈↓
R␈↓-image,␈α
rather␈α
than␈α∞the␈α
LISP
␈↓ ↓H␈↓expression␈α∃form.␈α∀Thus␈α∃to␈α∃ask␈α∀a␈α∃LISP␈α∃machine␈α∀to␈α∃evaluate␈α∃␈↓αcar[(A . B)]␈↓␈α∀we␈α∃present␈α∃it␈α∀with
␈↓ ↓H␈↓␈↓α(CAR (QUOTE (A . B)))␈↓.␈α What␈αthis␈αmeans␈αis␈αthat␈αwe␈αare␈αpresenting␈αour␈αprograms␈αto␈αthe␈αmachine
␈↓ ↓H␈↓as␈αdata␈αstructures␈αof␈αthe␈αlanguage␈↓π 61␈↓.␈α It␈αwould␈αbe␈αlike␈αexpressing␈αprograms␈αin␈αFortran␈αor␈αAlgol␈αas
␈↓ ↓H␈↓arrays␈αof␈αintegers;␈αthat␈αis,␈αthe␈αdata␈αstructures␈αof␈α␈↓↓those␈↓␈αlanguages.␈α We␈αwill␈αexplore␈αthe␈αimplications
␈↓ ↓H␈↓of␈αthis␈αapproach␈αto␈αprogramming␈αin␈αlater␈αsections,␈αbut␈αfor␈αnow␈αit␈αshould␈αhelp␈αto␈αknow␈αthat␈αwe␈αwill
␈↓ ↓H␈↓be making extensive use of this ␈↓
R␈↓-mapping.
␈↓ ↓H␈↓In␈α∀essence,␈α∃then,␈α∀there␈α∀are␈α∃␈↓↓two␈↓␈α∀LISP's:␈α∀there␈α∃is␈α∀the␈α∀algorithmic␈α∃language␈α∀and␈α∀there␈α∃is␈α∀the
␈↓ ↓H␈↓programming␈α∪language.␈α∩The␈α∪programming␈α∪language␈α∩is␈α∪a␈α∪data␈α∩structure␈α∪representation␈α∪of␈α∩the
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 60␈↓␈α∞In␈α∞LISP 1.5␈α∞␈↓αT␈↓␈α∂and␈α∞␈↓αF␈↓␈α∞were␈α∞used␈α∞as␈α∂the␈α∞representations␈α∞of␈α∞␈↓
t␈↓␈α∞and␈α∂␈↓
f␈↓;␈α∞the␈α∞atoms␈α∞␈↓αT␈↓␈α∞and␈α∂␈↓αF␈↓␈α∞were
␈↓ ↓H␈↓(permanently) bound to values ␈↓α*T*␈↓ and ␈↓αNIL␈↓.
␈↓ ↓H␈↓␈↓π 61␈↓ Compare this with the technique of Godel numbering in formal logic [Men 64].
␈↓ ↓H␈↓␈↓↓96 Evaluation␈↓ 53.2␈↓
␈↓ ↓H␈↓algorithmic␈αlanguage.␈α
The␈αalgorithmic␈α
language␈αis␈α
called␈αthe␈α
␈↓↓meta-language␈↓␈αor␈α
␈↓↓M-expr␈αLISP␈↓,␈α
and
␈↓ ↓H␈↓for historical purposes, the programming language is called ␈↓↓S-expr LISP␈↓.
␈↓ ↓H␈↓Review␈α∞the␈α∞␈↓αtgm␈↓'s␈α∞(Section 2.7)␈α∞now␈α∞that␈α∞you␈α∞know␈α∞that␈α∞they␈α∞are␈α∞evaluators␈α∞for␈α∞simple␈α∞subsets␈α
of
␈↓ ↓H␈↓LISP␈α∂expressions;␈α∂discover␈α∂what␈α∂LISP␈α∂expressions␈α∞were␈α∂encoded␈α∂in␈α∂arguments␈α∂to␈α∂the␈α∂␈↓αtgm␈↓'s␈α∞and
␈↓ ↓H␈↓verify␈α∪the␈α∩answers␈α∪you␈α∩obtained␈α∪earlier.␈α∪ Note␈α∩that␈α∪the␈α∩only␈α∪atoms␈α∩which␈α∪the␈α∪great␈α∩mothers
␈↓ ↓H␈↓recognize␈α∪are␈α∪␈↓αT␈↓␈α∪and␈α∪␈↓αNIL␈↓.␈α∪Any␈α∪other␈α∪atoms␈α∪elicit␈α∪an␈α∪error␈α∪message.␈α∪ What␈α∪do␈α∀other␈α∪atoms
␈↓ ↓H␈↓represent?␈α
Numerals␈α
are␈α
atoms␈αand␈α
are␈α
the␈α
␈↓
R␈↓-maps␈α
of␈αnumerals.␈α
We␈α
could␈α
extend␈α
␈↓αtgmoaf␈↓␈αto␈α
handle
␈↓ ↓H␈↓this␈αcase.␈α Atoms␈αare␈αalso␈αtranslations␈αof␈αvariables␈αand␈αfunction␈αnames.␈α So␈αone␈αtask␈αis␈αto␈αinclude␈αa
␈↓ ↓H␈↓mechanism␈α∞in␈α∞our␈α∞LISP␈α∞evaluator␈α∞to␈α∞handle␈α∞evaluation␈α∞of␈α∞variables␈α∞and␈α∞function␈α∞names.␈α∞We've
␈↓ ↓H␈↓already␈α∞seen␈α∞the␈α
necessary␈α∞mechanism␈α∞in␈α∞Section 2.6␈α
where␈α∞we␈α∞studied␈α
tables␈α∞as␈α∞an␈α∞abstract␈α
data
␈↓ ↓H␈↓stucture.␈α⊂The␈α⊂other␈α∂piece␈α⊂of␈α⊂LISP␈α∂which␈α⊂did␈α⊂not␈α∂appear␈α⊂in␈α⊂the␈α∂evaluator␈α⊂for␈α⊂polynomials␈α∂was
␈↓ ↓H␈↓conditional␈α
expressions.␈α
Before␈αhandling␈α
conditionals␈α
we␈α
wish␈αto␈α
enlarge␈α
on␈α
the␈αinformal␈α
discussion
␈↓ ↓H␈↓of tables.
␈↓ ↓H␈↓␈↓ ¬P␈↓↓3.3 Symbol Tables␈↓
␈↓ ↓H␈↓One␈αof␈αthe␈α
distinguishing␈αfeatures␈αof␈αcomputer␈α
science␈αis␈αits␈αstudy␈α
of␈αdevices␈αto␈αstore␈α
and␈αrecover
␈↓ ↓H␈↓information.␈α Any␈αformalism␈αwhich␈α
addresses␈αitself␈αto␈αcomputer␈α
science␈αmust␈αtake␈αthis␈αinto␈α
account.
␈↓ ↓H␈↓In␈α∞particular␈α
we␈α∞must␈α
be␈α∞able␈α
to␈α∞handle␈α∞the␈α
effect␈α∞of␈α
binding,␈α∞that␈α
is,␈α∞the␈α
association␈α∞of␈α∞a␈α
value
␈↓ ↓H␈↓with␈α
a␈α∞name.␈α
A␈α
common␈α∞notion␈α
used␈α
to␈α∞describe␈α
this␈α
is␈α∞the␈α
symbol␈α
table.␈α∞This␈α
is␈α
the␈α∞device␈α
we
␈↓ ↓H␈↓used informally in Section 2.6. We will review some of that discussion here.
␈↓ ↓H␈↓In␈α
essence,␈α
a␈α
symbol␈αtable␈α
is␈α
simply␈α
a␈α
set␈αof␈α
ordered␈α
pairs␈α
of␈α
objects;␈αone␈α
of␈α
the␈α
elements␈α
of␈αeach
␈↓ ↓H␈↓pair␈α⊂is␈α⊂a␈α∂name;␈α⊂the␈α⊂other␈α∂is␈α⊂its␈α⊂value.␈α⊂ This␈α∂means␈α⊂that␈α⊂symbol␈α∂tables␈α⊂can␈α⊂be␈α⊂characterized␈α∂as
␈↓ ↓H␈↓relations␈α⊂or␈α∂perhaps␈α⊂even␈α⊂as␈α∂functions.␈α⊂ This␈α∂characterization␈α⊂is␈α⊂indeed␈α∂viable.␈α⊂On␈α⊂page 82␈α∂we
␈↓ ↓H␈↓showed␈αthat␈αa␈α
table␈αcould␈αbe␈αconstructed␈α
and␈αmaintained␈αin␈αa␈α
manner␈αpreserving␈αset-ness.␈α
As␈αan
␈↓ ↓H␈↓abstract␈αoperation,␈αfinding␈αan␈αelement␈αin␈αa␈αsymbol␈αtable␈αis␈αalso␈αquite␈αsimple:␈αgiven␈αa␈αset␈αof␈α
ordered
␈↓ ↓H␈↓pairs␈αand␈αa␈αvariable,␈α
find␈αa␈αpair␈αwith␈α
first␈αelement␈αthe␈αsame␈α
as␈αthe␈αgiven␈αvariable.␈α This␈α
operation
␈↓ ↓H␈↓can␈α∂be␈α∂described␈α∂as␈α∂function␈α∂application␈α∂where␈α∞the␈α∂function␈α∂being␈α∂applied␈α∂is␈α∂the␈α∂table␈α∂and␈α∞the
␈↓ ↓H␈↓argument is the name component. That is: ␈↓αlocate[x;tbl] = tbl(x)␈↓.
␈↓ ↓H␈↓This␈α∀level␈α∀of␈α∀abstraction␈α∀was␈α∀a␈α∀bit␈α∀too␈α∀spartan;␈α∀maintaining␈α∀such␈α∀tables␈α∀is␈α∀computationally
␈↓ ↓H␈↓expensive,␈αand␈αwe␈αwill␈α␈↓↓have␈↓␈αto␈αgive␈αa␈α␈↓αlocate␈↓␈αalgorithm␈αsooner␈αor␈αlater.␈α The␈αlevel␈αof␈αabstraction␈αwe
␈↓ ↓H␈↓envisioned␈αviewed␈αa␈αsymbol␈αtable␈αas␈αa␈α␈↓↓sequence␈↓␈αof␈αpairs,␈αeach␈αpair␈αrepresenting␈αa␈αvariable␈αand␈αits
␈↓ ↓H␈↓corresponding␈α∞value.␈α∞ The␈α∞table␈α∞manipulating␈α∞algorithms,␈α∞given␈α∞in␈α∞Section 2.6,␈α∞depended␈α
heavily
␈↓ ↓H␈↓on␈α∩the␈α∩implied␈α∩sequencing␈α∩of␈α∩call-by-value␈α∩and␈α∩recursion.␈α∩ Since␈α∩this␈α∩was␈α∩consistent␈α∩with␈α⊃the
␈↓ ↓H␈↓explicit␈αsequencing␈αused␈αin␈αadding␈αelements␈αto␈αthe␈αtable,␈αwe␈αachieved␈αthe␈αdesired␈αeffect.␈αWe␈αfound
␈↓ ↓H␈↓the␈α∂expected␈α∞bindings,␈α∂even␈α∂though␈α∞there␈α∂may␈α∞have␈α∂been␈α∂other␈α∞candidates␈α∂in␈α∞the␈α∂tables.␈α∂In␈α∞the
␈↓ ↓H␈↓remaining␈α⊗sections␈α⊗of␈α⊗this␈α⊗chapter␈α⊗we␈α⊗will␈α⊗utilize␈α⊗more␈α⊗features␈α⊗of␈α⊗this␈α⊗interplay␈α⊗between
␈↓ ↓H␈↓representation␈αof␈αdata␈αand␈αcalling␈αstyle␈αof␈αalgorithm.␈αSymbol␈αtables␈αare␈αjust␈αthe␈αfirst␈αmanifestation
␈↓ ↓H␈↓of this phenomenon.
␈↓ ↓H␈↓␈↓↓3.3␈↓ @Symbol Tables 97␈↓
␈↓ ↓H␈↓Symbol␈αtables␈α
are␈αalso␈α
known␈αas␈α
association␈αlists␈α
or␈α␈↓↓a-lists␈↓;␈α
thus␈α␈↓αassoc␈↓␈α
is␈αthe␈α
traditional␈αname␈αof␈α
our
␈↓ ↓H␈↓LISP␈α
function␈α
to␈α
search␈α
a␈α
symbol␈α
table.␈α
The␈α
binary␈α
function␈α
␈↓αassoc␈↓␈α
expects␈α
a␈α
name␈α
and␈α
a␈α
symbol
␈↓ ↓H␈↓table␈α∞as␈α
arguments.␈α∞ It␈α
will␈α∞examine␈α∞the␈α
table␈α∞from␈α
left␈α∞to␈α∞right,␈α
looking␈α∞for␈α
the␈α∞first␈α∞pair␈α
whose
␈↓ ↓H␈↓name-component␈αmatches␈α
the␈αgiven␈αname.␈α
If␈αa␈αpair␈α
is␈αfound,␈αthen␈α
that␈αpair␈αis␈α
returned;␈αif␈αno␈α
such
␈↓ ↓H␈↓pair␈α∂is␈α∞found,␈α∂the␈α∞result␈α∂is␈α∂undefined.␈α∞ We␈α∂will␈α∞need␈α∂to␈α∂designate␈α∞a␈α∂selector,␈α∞␈↓αname␈↓,␈α∂to␈α∂locate␈α∞the
␈↓ ↓H␈↓name-component of a pair, and another selector, ␈↓αvalue␈↓, to retrieve the value-component.
␈↓ ↓H␈↓α␈↓ αXassoc[x;l] <=␈↓ βx[eq[name[first[l]];x] → first[l];
␈↓ ↓H␈↓α␈↓ αX␈↓ βx ␈↓
t␈↓α → assoc[x;rest[l]]]
␈↓ ↓H␈↓If␈αthe␈αtable␈αis␈αvery␈αlong␈αand␈αthe␈αdesired␈αpair␈αis␈αclose␈αto␈αthe␈αend␈αof␈αthe␈αtable,␈αthen␈αwe␈αwill␈αbe␈αin␈α
for
␈↓ ↓H␈↓a␈αvery␈α
long␈αsearch.␈α
The␈αsearch␈α
scheme␈αencoded␈α
in␈α␈↓αassoc␈↓␈α
is␈αcalled␈α
␈↓↓linear␈αsearch␈↓,␈α
and␈αis␈α
unnecessarily
␈↓ ↓H␈↓inefficient␈α
for␈α
tables␈α
of␈α
substantial␈α
length.␈α
However␈αthe␈α
phenomemona␈α
we␈α
wish␈α
to␈α
study␈α
here␈αare
␈↓ ↓H␈↓not␈α↔related␈α↔to␈α_efficiency␈α↔of␈α↔searching␈α_methods.␈α↔ We␈α↔will␈α↔come␈α_back␈α↔to␈α↔symbol␈α_tables␈α↔in
␈↓ ↓H␈↓Section 5.6␈α∞to␈α∞study␈α∞the␈α∞problems␈α∞of␈α∞efficient␈α∞storage␈α∞and␈α∞retrieval␈α∞of␈α∞information.␈α∞It␈α∂will␈α∞suffice
␈↓ ↓H␈↓now␈α∞simply␈α∞to␈α∞think␈α∞of␈α∞a␈α∞symbol␈α∞table␈α∞as␈α∞represented␈α∞in␈α∞LISP␈α∞by␈α∞a␈α∞list␈α∞of␈α∞dotted␈α∞pairs,␈α∞a␈α
name
␈↓ ↓H␈↓dotted␈α⊂with␈α⊂value.␈α⊃ In␈α⊂this␈α⊂representation,␈α⊂then,␈α⊃␈↓αname[x]␈α⊂<=␈α⊂car[x]␈↓,␈α⊂and␈α⊃␈↓αvalue[x] <= cdr[x]␈↓.␈α⊂ For
␈↓ ↓H␈↓completeness,␈α
we␈αshould␈α
also␈αspecify␈α
a␈α
constructor.␈αThough␈α
we␈αwon't␈α
need␈α
it␈αfor␈α
a␈αwhile,␈α
its␈αname␈α
is
␈↓ ↓H␈↓␈↓αmkent␈↓;␈αit␈αwill␈α
take␈αa␈αname␈α
and␈αa␈αvalue␈α
and␈αreturn␈αa␈α
new␈αsymbol␈αtable␈α
entry.␈αIts␈αrepresentation␈α
here
␈↓ ↓H␈↓is ␈↓αmkent[x;y] <= cons[x;y]␈↓.
␈↓ ↓H␈↓Recall␈α
that␈α
we␈α
are␈α
representing␈α
variables␈α∞as␈α
atoms;␈α
if␈α
␈↓αx,␈α
y,␈α
␈↓and␈α∞␈↓αz␈↓␈α
had␈α
current␈α
values␈α
␈↓α2,␈α
3,␈α∞␈↓and␈α
␈↓α4␈↓,
␈↓ ↓H␈↓then a symbol table describing that fact could be encoded as:
␈↓ ↓H␈↓␈↓ ¬3␈↓α((X . 2) (Y . 3) (Z . 4)) .␈↓
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓␈↓ ∧B␈↓αassoc[Y; ((X . 2) (Y . 3) (Z . 4))] = (Y . 3)
␈↓ ↓H␈↓α␈↓ ∧Xassoc[U; ((X . 2) (Y . 3) (Z . 4))] ␈↓ = ␈↓λB␈↓.
␈↓ ↓H␈↓␈↓ ¬\␈↓αassoc[U; ( )] ␈↓ = ␈↓λB␈↓.
␈↓ ↓H␈↓We␈α⊃must␈α⊃also␈α⊃represent␈α⊃bindings␈α⊃of␈α⊂variables␈α⊃to␈α⊃non-numeric␈α⊃S-exprs.␈α⊃ For␈α⊃example,␈α⊃we␈α⊂must
␈↓ ↓H␈↓represent␈αinformation␈αlike:␈α"the␈αcurrent␈α
value␈αof␈α␈↓αx␈↓␈αis␈α␈↓αA␈↓".␈α We␈α
will␈αplace␈αthe␈αdotted-pair␈α␈↓α(X␈α.␈α
A)␈↓␈αin
␈↓ ↓H␈↓the␈α∂table.␈α∞Now␈α∂this␈α∂representation␈α∞is␈α∂certainly␈α∞open␈α∂to␈α∂question:␈α∞why␈α∂not␈α∂add␈α∞␈↓α(X . (QUOTE A))␈↓?
␈↓ ↓H␈↓The␈α
latter␈α
notation␈α
is␈αmore␈α
consistent␈α
with␈α
our␈αconception␈α
of␈α
representation␈α
espoused␈α
on␈αpage 52.
␈↓ ↓H␈↓That␈αis,␈αwe␈αmap␈α
LISP␈αexpressions␈αto␈αS-expressions;␈α
perform␈αthe␈αcalculations␈αon␈αthis␈α
representation,
␈↓ ↓H␈↓and␈α
finally␈α
␈↓↓reinterpret␈↓␈α
the␈α
result␈α
of␈α
this␈α
calculation␈α
as␈α
a␈α
LISP␈α
expression.␈α
The␈α
representation␈α
we
␈↓ ↓H␈↓have␈αchosen␈α
for␈αsymbol␈α
tables␈αobviates␈αthe␈α
last␈αreinterpretation␈α
step;␈αrecall␈α
the␈αdiagram␈αon␈α
page 93.
␈↓ ↓H␈↓Now␈α∞it␈α∞will␈α∞turn␈α∞out␈α∞that␈α∞for␈α∞our␈α∞initial␈α∞subsets␈α∞of␈α∞LISP␈α∞this␈α∞reinterpretation␈α∞step␈α∂simply␈α∞would
␈↓ ↓H␈↓involve␈α"stripping"␈αthe␈α␈↓αQUOTE␈↓s.␈α The␈αonly␈α"values"␈αwhich␈αa␈αcomputation␈αcan␈αreturn␈αare␈αconstants;
␈↓ ↓H␈↓later␈α
things␈α
will␈α
become␈α
more␈α
difficult.␈α
Perhaps␈α
this␈α
representation␈α
of␈α
table␈α
entries␈α
is␈α
a␈α
poor␈αone;␈α
we
␈↓ ↓H␈↓will␈α
see.␈α
In␈α
studying␈α
any␈αexisting␈α
language,␈α
or␈α
contemplating␈α
the␈αdesign␈α
of␈α
any␈α
new␈α
one,␈α
we␈αmust
␈↓ ↓H␈↓question each detail of representation. Decisions made too early can have serious consequences.
␈↓ ↓H␈↓␈↓↓98 Evaluation␈↓ 53.3␈↓
␈↓ ↓H␈↓Before␈α
continuing␈α
we␈α
should␈α
take␈α
stock␈α
of␈α
our␈α
current␈α
position;␈α
in␈α
this␈α
section␈α
we␈α
have␈α
recreated
␈↓ ↓H␈↓the␈αtable-lookup␈αmechanism␈αwe␈αused␈αin␈αSection 2.6,␈αbut␈αnow␈αwe␈αare␈αpaying␈αa␈αbit␈αmore␈αattention␈αto
␈↓ ↓H␈↓representation.␈α∞We␈α
can␈α∞locate␈α
things␈α∞in␈α
a␈α∞table␈α∞and␈α
we␈α∞have␈α
seen␈α∞how␈α
calling␈α∞functions␈α∞can␈α
add
␈↓ ↓H␈↓values␈αto␈α
a␈αtable.␈α
We␈αhave␈α
said␈αnothing␈α
about␈αadding␈α
function␈αdefinitions␈α
to␈αthe␈αtables.␈α
Abstractly
␈↓ ↓H␈↓we␈α⊂know␈α⊂how␈α⊂to␈α⊂extract␈α∂the␈α⊂definition␈α⊂from␈α⊂the␈α⊂table␈α⊂and␈α∂apply␈α⊂it.␈α⊂We␈α⊂must␈α⊂give␈α⊂an␈α∂explicit
␈↓ ↓H␈↓representation␈αof␈αthe␈αstorage␈αof␈αa␈αfunction.␈αThis␈αturns␈αout␈αto␈αbe␈αa␈αreasonably␈α
non-trivial␈αproblem.
␈↓ ↓H␈↓We␈α∞have␈α∞seen␈α∞that␈α∞it␈α∞is␈α∞possible␈α∞to␈α
mechanize␈α∞at␈α∞least␈α∞one␈α∞scheme␈α∞for␈α∞evaluation␈α∞of␈α∞functions␈α
--
␈↓ ↓H␈↓call-by-value,␈αevaluating␈αarguments␈αfrom␈αleft␈αto␈αright.␈α We␈αhave␈αseen␈αthat␈αit␈αis␈αpossible␈αto␈αtranslate
␈↓ ↓H␈↓LISP␈αexpressions␈αinto␈αS-exprs␈αin␈αsuch␈αa␈αway␈α
that␈αwe␈αcan␈αwrite␈αa␈αLISP␈αfunction␈αwhich␈αwill␈α
act␈αas
␈↓ ↓H␈↓an␈αevaluator␈αfor␈αsuch␈αtranslations.␈α In␈αthe␈αprocess␈αwe␈αhave␈αhad␈αto␈αmechanize␈αthe␈αintuitive␈αdevices
␈↓ ↓H␈↓we␈α⊂might␈α⊂mentally␈α⊂use␈α⊂to␈α⊂recall␈α⊂the␈α⊂definition␈α⊂of␈α⊂functions␈α⊂and␈α⊂to␈α⊂recall␈α⊂the␈α⊂current␈α⊂values␈α⊂of
␈↓ ↓H␈↓variables.␈α∂ It␈α⊂became␈α∂clear␈α⊂that␈α∂the␈α∂mechanism␈α⊂of␈α∂symbol␈α⊂tables␈α∂could␈α∂be␈α⊂used.␈α∂ To␈α⊂associate␈α∂a
␈↓ ↓H␈↓variable␈α∞with␈α∞a␈α∞value␈α∞was␈α∞easy.␈α∞ To␈α
associate␈α∞a␈α∞function␈α∞name␈α∞with␈α∞its␈α∞definition␈α∞required␈α
some
␈↓ ↓H␈↓care.␈α⊃ That␈α∩is,␈α⊃part␈α∩of␈α⊃the␈α∩definition␈α⊃of␈α∩a␈α⊃function␈α∩involves␈α⊃the␈α∩proper␈α⊃association␈α∩of␈α⊃formal
␈↓ ↓H␈↓parameters␈α
with␈α
the␈αbody␈α
of␈α
the␈α
definition.␈αThe␈α
next␈α
section␈αintroduces␈α
a␈α
notation␈α
for␈αdescribing
␈↓ ↓H␈↓function definitions.
␈↓ ↓H␈↓␈↓ ¬n␈↓↓3.4 ␈↓αλ␈↓↓-notation␈↓α
␈↓ ↓H␈↓Recall␈α⊂our␈α⊂discussion␈α∂of␈α⊂the␈α⊂problems␈α∂of␈α⊂representation␈α⊂of␈α∂function␈α⊂definitions.␈α⊂This␈α∂discussion
␈↓ ↓H␈↓began␈α
on␈α
page 77␈α
and␈α
our␈α
conclusion␈α
was␈α
that␈α
to␈α
represent␈α
a␈α
definition␈α
like␈α
␈↓αf[x;y] <= ␈↓λx␈↓␈α
we␈α
needed␈α
a
␈↓ ↓H␈↓symbol␈α
table␈α
entry␈α
with␈α
name␈α␈↓αf␈↓␈α
and␈α
a␈α
value␈α
part␈α
which␈αcontained␈α
the␈α
body␈α
of␈α
the␈α
definition,␈α␈↓λx␈↓,␈α
and
␈↓ ↓H␈↓the␈α∂list␈α∂of␈α∂formal␈α∂parameters,␈α∂␈↓α[x;y]␈↓.␈α∂ LISP␈α∂uses␈α∂the␈α∂λ-notation␈α∂to␈α∂lend␈α∂precision␈α∂to␈α∂our␈α∞informal
␈↓ ↓H␈↓discussion of function representation.
␈↓ ↓H␈↓The␈α
λ-notation␈α
is␈α
derived␈α
from␈α
the␈α
␈↓λλ␈↓-calculus,␈α
a␈α
formalism␈α
invented␈α
by␈α
the␈α
logician␈αAlonzo␈α
Church
␈↓ ↓H␈↓([Chu 41])␈α∞to␈α∞model␈α∞functions␈α∞which␈α∞are␈α∞describable␈α∞by␈α∞algorithms.␈α∞ The␈α∞␈↓λλ␈↓-calculus␈α∞is␈α∞useful␈α∞for
␈↓ ↓H␈↓discussing␈α∩the␈α∪concepts␈α∩of␈α∩function␈α∪and␈α∩function␈α∩application.␈α∪Since␈α∩many␈α∪algorithms␈α∩compute
␈↓ ↓H␈↓functions␈αand␈αsince␈αfunction␈αapplication␈αis␈αsimulated␈αby␈αprocedure␈αcalls,␈αthe␈αcalculus␈αis␈α
well␈αsuited
␈↓ ↓H␈↓for␈αa␈αpurified␈αdiscussion␈αof␈αprocedures␈αin␈αprogramming␈αlanguages.␈αWe␈αshall␈αoutline␈αthe␈α␈↓λλ␈↓-calculus
␈↓ ↓H␈↓and its relation to computer science in Section 3.13.
␈↓ ↓H␈↓The␈αλ-notation␈αwas␈αintroduced␈αinto␈αprogramming␈αlanguages␈αby␈αJohn␈αMcCarthy␈αin␈αthe␈αdescription
␈↓ ↓H␈↓of␈αLISP␈α([McC 60]).␈α There␈αare␈αseveral␈αimportant␈αdistinctions␈αbetween␈αChurch's␈α␈↓λλ␈↓-calculus␈αand␈α
the
␈↓ ↓H␈↓λ-notation of McCarthy. We will point out the discrepancies in Section 3.13.
␈↓ ↓H␈↓We␈α⊃begin␈α∩by␈α⊃exemplifying␈α∩the␈α⊃need␈α∩for␈α⊃more␈α∩precise␈α⊃terminology.␈α∩ We␈α⊃have␈α∩been␈α⊃informally
␈↓ ↓H␈↓writing␈α␈↓αf[x;y] <= x*y + y␈↓␈αas␈αa␈αdefinition␈αof␈αthe␈αfunction␈α␈↓αf␈↓.␈αThis␈αnotation␈αis␈αsupposed␈αto␈αconvey␈αthe
␈↓ ↓H␈↓following␈α∂intent:␈α∂␈↓αf␈↓␈α∂is␈α∂the␈α∂name␈α∂of␈α∂a␈α∂function␈α∂or␈α∂rule;␈α∂whenever␈α∂␈↓αf␈↓␈α∂is␈α∂supplied␈α∂with␈α∂two␈α∞numeric
␈↓ ↓H␈↓arguments␈α⊃it␈α∩is␈α⊃supposed␈α∩to␈α⊃multiply␈α⊃those␈α∩arguments␈α⊃and␈α∩add␈α⊃the␈α⊃result␈α∩to␈α⊃the␈α∩second.␈α⊃The
␈↓ ↓H␈↓resulting␈α∩sum␈α⊃is␈α∩the␈α∩desired␈α⊃answer.␈α∩ Since␈α⊃informality␈α∩is␈α∩susceptible␈α⊃to␈α∩ambiguity,␈α∩we␈α⊃should
␈↓ ↓H␈↓analyze␈α∞the␈α∂"<="-notation␈α∞more␈α∂closely.␈α∞Though␈α∂we␈α∞say␈α∂␈↓αf␈↓␈α∞is␈α∂being␈α∞defined,␈α∂it␈α∞is␈α∂not␈α∞␈↓αf␈↓,␈α∂but␈α∞␈↓αf[x;y]␈↓
␈↓ ↓H␈↓␈↓↓3.4␈↓ }␈↓αλ␈↓↓-notation 99␈↓α
␈↓ ↓H␈↓which␈αappears␈α
to␈αthe␈α
left␈αof␈αthe␈α
"<="-symbol.␈α First,␈α
␈↓αf[x;y]␈↓␈αdoes␈α␈↓↓not␈↓␈α
denote␈αa␈α
function,␈α␈↓αf␈↓␈α
denotes␈αa
␈↓ ↓H␈↓function.␈α∩ To␈α∩see␈α∩what␈α⊃␈↓αf[x;y]␈↓␈α∩means␈α∩consider␈α∩the␈α∩following␈α⊃example.␈α∩ When␈α∩we␈α∩are␈α∩asked␈α⊃to
␈↓ ↓H␈↓evaluate␈α∞␈↓αcar[(A . B)]␈↓␈α∞we␈α
say␈α∞the␈α∞value␈α
is␈α∞␈↓αA␈↓.␈α∞ ␈↓αcar[(A . B)]␈↓␈α∞is␈α
an␈α∞expression␈α∞to␈α
be␈α∞evaluated;␈α∞it␈α∞is␈α
a
␈↓ ↓H␈↓LISP␈αform.␈α If␈α␈↓αcar[(A . B)]␈↓␈αis␈αa␈αform␈αthen␈αso␈αis␈α␈↓αcar[x]␈↓;␈αonly␈αnow␈αthe␈αvalue␈αof␈αthe␈αform␈αdepends␈αon
␈↓ ↓H␈↓the␈αcurrent␈α
value␈αassigned␈α
to␈αthe␈α
variable␈α␈↓αx␈↓.␈α
So␈αthe␈α
␈↓↓function␈↓␈αis␈α
␈↓αcar␈↓;␈αthe␈α
␈↓↓form␈↓␈αis␈α␈↓αcar[x]␈↓.␈α
Therefore,
␈↓ ↓H␈↓the␈α∞function␈α
is␈α∞␈↓αf␈↓;␈α
␈↓αf[x;y]␈↓␈α∞is␈α
a␈α∞form,␈α
and␈α∞so␈α
is␈α∞␈↓αx*y + y␈↓.␈α
The␈α∞informal␈α
notation␈α∞has␈α
a␈α∞form␈α∞on␈α
both
␈↓ ↓H␈↓sides␈αof␈αthe␈α"<=".␈αWe␈αwould␈αlike␈αa␈αnotation␈αwhich␈αclearly␈αshows␈αwhat␈αis␈αbeing␈αdefined␈αand␈αwhat␈αis
␈↓ ↓H␈↓given.
␈↓ ↓H␈↓Further,␈α
our␈αnotation␈α
has␈α
really␈αbeen␈α
specifying␈α
more␈αthan␈α
just␈α
the␈αname.␈α
The␈α
notation␈αspecifies
␈↓ ↓H␈↓the␈αformal␈αparameters␈α(␈↓αx␈↓␈αand␈α␈↓αy␈↓)␈αand␈αthe␈αorder␈αin␈αwhich␈αwe␈αare␈αto␈αassociate␈αactual␈αparameters␈αin␈αa
␈↓ ↓H␈↓call␈αwith␈αthe␈αformal␈αparameters␈αof␈αthe␈αdefinition␈α(␈↓αx␈↓␈αwith␈αthe␈αfirst,␈α␈↓αy␈↓␈αwith␈αthe␈αsecond).␈α More␈αsubtly,
␈↓ ↓H␈↓the␈αnotation␈α
tells␈α␈↓↓which␈↓␈α
variables␈αin␈α
the␈αfunction␈α
body␈αare␈α
to␈αbe␈α
supplied␈αvalues␈α
when␈αthe␈α
function
␈↓ ↓H␈↓is␈α
called.␈α
For␈α
example␈α
define␈α
␈↓αg[x] <= x*y + y␈↓;␈α
then␈αthe␈α
expression␈α
␈↓αg[2]␈↓␈α
specifies␈α
that␈α
␈↓αx␈↓␈α
is␈α
to␈αreceive␈α
a
␈↓ ↓H␈↓value ␈↓α2␈↓, but leaves unspecified what the value of ␈↓αy␈↓ should be␈↓π 62␈↓.
␈↓ ↓H␈↓We␈αalso␈αwish␈αto␈αhave␈αa␈αnotation␈αso␈αthat␈αfunction␈αdefinitions␈αcan␈αbe␈αinserted␈αinto␈αthe␈αsymbol␈αtable
␈↓ ↓H␈↓as␈α⊃"values"␈α⊃assigned␈α⊃to␈α⊃names.␈α⊃They␈α⊃will␈α⊃be␈α⊃parametric␈α⊃values,␈α⊃but␈α⊃they␈α⊃will␈α⊃be␈α∩values.␈α⊃ The
␈↓ ↓H␈↓λ-notation␈α
performs␈αthis␈α
task␈αby␈α
preceding␈α
the␈αfunction␈α
body␈αwith␈α
a␈α
list␈αof␈α
variables,␈αcalled␈α
␈↓↓lambda
␈↓ ↓H␈↓↓list␈↓.␈αThe␈αlambda␈αlist␈αhas␈αbeen␈αpreviously␈αcalled␈αthe␈αformal␈αparameter␈αlist;␈αeither␈αterm␈αis␈α
acceptable.
␈↓ ↓H␈↓Each␈α⊂parameter␈α⊃in␈α⊂the␈α⊃lambda␈α⊂list␈α⊃is␈α⊂called␈α⊃a␈α⊂lambda␈α⊃variable␈α⊂(or␈α⊃a␈α⊂formal␈α⊃parameter).␈α⊂ The
␈↓ ↓H␈↓resulting␈α
construct␈αis␈α
preceded␈αby␈α
"λ["␈αand␈α
followed␈αby␈α
"]".␈α Using␈α
the␈αabove␈α
example,␈αthe␈α
identifier
␈↓ ↓H␈↓␈↓αf␈↓␈α
denotes␈α
exactly␈α
the␈α
same␈α
LISP␈αfunction␈α
as␈α
␈↓αλ[[x;y] x*y + y]␈↓.␈α
The␈α
λ-notation␈α
introduces␈αnothing␈α
new
␈↓ ↓H␈↓as␈α∪far␈α∪as␈α∪our␈α∪intuitive␈α∪binding␈α∪and␈α∩evaluation␈α∪processes␈α∪are␈α∪concerned;␈α∪it␈α∪only␈α∪makes␈α∩these
␈↓ ↓H␈↓operations more clear.
␈↓ ↓H␈↓One␈α∂benefit␈α∂of␈α∂the␈α⊂λ-notation␈α∂is␈α∂that␈α∂we␈α⊂need␈α∂not␈α∂give␈α∂explicit␈α⊂names␈α∂to␈α∂functions␈α∂in␈α⊂order␈α∂to
␈↓ ↓H␈↓perform␈α∞the␈α
evaluation.␈α∞Evaluation␈α
of␈α∞expressions␈α
involving␈α∞such␈α
anonymous␈α∞functions␈α∞is␈α
within
␈↓ ↓H␈↓the␈α
province␈α
of␈αLISP.␈α
Currently,␈α
we␈αwill␈α
restrict␈α
our␈α
discussion␈αto␈α
λ-expressions␈α
which␈αare␈α
function
␈↓ ↓H␈↓constants,␈α∞just␈α∞like␈α∞␈↓αA␈↓␈α∞is␈α∞an␈α∞S-expr␈α∞constant.␈α∞Since␈α∞a␈α∞λ-expression␈α∞is␈α∞a␈α∞constant,␈α∞its␈α∞value␈α∞is␈α
itself.
␈↓ ↓H␈↓LISP␈α∂will␈α∂evaluate␈α∂an␈α⊂application␈α∂involving␈α∂a␈α∂λ-expression␈α∂in␈α⊂two␈α∂stages;␈α∂first,␈α∂it␈α∂will␈α⊂bind␈α∂the
␈↓ ↓H␈↓evaluated actual parameters to the λ-variables, and then it will evaluate the function body.
␈↓ ↓H␈↓Consider, for example:
␈↓ ↓H␈↓␈↓ ¬O␈↓αλ[[x;y] x␈↓π2␈↓α + y][2;3] ␈↓.
␈↓ ↓H␈↓We associate ␈↓α2␈↓ with ␈↓αx␈↓ and ␈↓α3␈↓ with ␈↓αy␈↓ and evaluate the expression:
␈↓ ↓H␈↓␈↓ ε(␈↓αx␈↓π2␈↓α + y␈↓.
␈↓ ↓H␈↓This calculation should give ␈↓α7␈↓ as value.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 62␈↓ Note also, that the "values" for + and * are also unspecified.
␈↓ ↓H␈↓␈↓↓100 Evaluation␈↓ 23.4␈↓
␈↓ ↓H␈↓Or␈α∞to␈α
evaluate: ␈↓αλ[[x]␈α∞cdr[car[x]]][((A␈α
.␈α∞B).␈α
C)]␈↓, ␈α∞we␈α
bind␈α∞␈↓αx␈↓␈α
to␈α∞the␈α
S-expression␈α∞␈↓α((A . B). C)␈↓␈α
and
␈↓ ↓H␈↓evaluate␈α∞the␈α∞function␈α∂body.␈α∞The␈α∞LISP␈α∂evaluation␈α∞scheme␈α∞first␈α∂entails␈α∞evaluating␈α∞␈↓αcar[x]␈↓␈α∂with␈α∞the
␈↓ ↓H␈↓current binding of ␈↓αx␈↓; this result, ␈↓α(A . B)␈↓, is passed to ␈↓αcdr␈↓. That calculation finally returns ␈↓αB␈↓.
␈↓ ↓H␈↓The λ-notation can be used anywhere LISP expects to find a function, for example:
␈↓ ↓H␈↓␈↓ ∧_␈↓αλ[[x] first[x]]
␈↓ ↓H␈↓α␈↓ ∧_ [λ[[y] rest[y]][(A B)]]␈↓
␈↓ ↓H␈↓This expression is a complicated way of writing:
␈↓ ↓H␈↓␈↓ βz␈↓αf[g[(A B)]]␈↓ where ␈↓αf[x] <= first[x] ␈↓and ␈↓αg[y] <= rest[y]␈↓.
␈↓ ↓H␈↓Though␈αthe␈αsecond␈αform␈αis␈αperhaps␈αeasier␈αfor␈αus␈αto␈αcomprehend,␈αthe␈αfirst␈αform␈α␈↓↓is␈↓␈α
equivalent␈αand
␈↓ ↓H␈↓will␈αbe␈αacceptable␈αto␈αthe␈αevaluator.␈α In␈αfact,␈αthe␈αevaluation␈αof␈αthe␈αsecond␈αformulation␈αwill␈αreduce␈α
to
␈↓ ↓H␈↓the first formulation on its way to final evaluation.
␈↓ ↓H␈↓␈↓ βO␈↓αλ[[x] first[x]][λ[[y] rest[y]][(A B)]] = λ[[x] first[x]][(B)] = B␈↓
␈↓ ↓H␈↓LISP␈αevaluation␈αrequires␈αcare.␈αFor␈αexample␈αthe␈αLISP␈αfunction␈α␈↓αλ[[x]2]␈↓␈αis␈α␈↓↓not␈↓␈αthe␈αconstant␈αfunction
␈↓ ↓H␈↓which␈αalways␈αgives␈αvalue␈α␈↓α2␈↓.␈α The␈αevaluation␈αof␈αan␈αexpression␈αinvolving␈αthis␈αfunction␈αrequires␈αthe
␈↓ ↓H␈↓evaluation␈α∞of␈α∞the␈α∞actual␈α∞parameter␈α∞associated␈α∂with␈α∞␈↓αx␈↓.␈α∞ That␈α∞computation␈α∞may␈α∞not␈α∂terminate.␈α∞For
␈↓ ↓H␈↓example,␈αconsider␈α
␈↓αλ[[x]2][fact[-1]]␈↓␈αwhere␈α
␈↓αfact␈↓␈αis␈αthe␈α
LISP␈αimplementation␈α
of␈αthe␈α
factorial␈αfunction
␈↓ ↓H␈↓given on page 42.
␈↓ ↓H␈↓Since␈αwe␈αintend␈αto␈αinclude␈αλ-expressions␈αin␈αour␈αlanguage␈αwe␈αmust␈αinclude␈αan␈α␈↓
R␈↓-mapping␈α
of␈αthem
␈↓ ↓H␈↓into S-expression form. The character λ will be translated to ␈↓αLAMBDA␈↓:
␈↓ ↓H␈↓␈↓ βh␈↓
R␈↓∞( ␈↓αλ[[x␈↓β1␈↓α; ...; x␈↓βn␈↓α] ␈↓λx␈↓α] ␈↓∞)␈↓α = (LAMBDA (X␈↓β1␈↓α ... X␈↓βn␈↓α) ␈↓
R␈↓∞( ␈↓λx␈↓α ␈↓∞)␈↓α)␈↓
␈↓ ↓H␈↓Here are some examples of ␈↓αλ␈↓-expressions and their ␈↓
R␈↓-translations:
␈↓ ↓H␈↓␈↓ β≡␈↓
R␈↓∞( ␈↓αλ[[x;y] x␈↓π2␈↓α + y] ␈↓∞)␈↓α = (LAMBDA (X Y) (PLUS (EXPT X 2) Y))
␈↓ ↓H␈↓α␈↓ βλ␈↓
R␈↓∞( ␈↓αλ[[x;y] cons[car[x];y]] ␈↓∞)␈↓α = (LAMBDA (X Y) (CONS (CAR X) Y))
␈↓ ↓H␈↓To␈α∞complete␈α∞our␈α∞introduction␈α∞of␈α∞λ-expressions,␈α∂our␈α∞LISP␈α∞syntax␈α∞equations␈α∞will␈α∞be␈α∂augmented␈α∞to
␈↓ ↓H␈↓include:
␈↓ ↓H␈↓<function>␈↓ αh::= λ[<varlist><form>]
␈↓ ↓H␈↓<varlist>␈↓ αh::= [<variable>; ... ; <variable>] ␈↓π 63␈↓
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 63␈↓ Recall that this use of ellipses means "zero or more occurrences of <variable>".
␈↓ ↓H␈↓␈↓↓3.4␈↓ o␈↓αλ␈↓↓-notation 101␈↓α
␈↓ ↓H␈↓Besides␈α∞giving␈α∞a␈α∞clear␈α∞notation␈α∞for␈α∂function␈α∞definitions,␈α∞the␈α∞λ-notation␈α∞is␈α∞a␈α∂useful␈α∞computational
␈↓ ↓H␈↓device.
␈↓ ↓H␈↓Consider the following sketch of a function definition:
␈↓ ↓H␈↓␈↓ ∧e␈↓αg <= λ[[x][␈↓λp␈↓α[lic[x]] → lic[x]; .... x ...]]␈↓,
␈↓ ↓H␈↓where ␈↓αlic␈↓ may be a ␈↓l␈↓ong ␈↓i␈↓nvolved ␈↓c␈↓alculation, and ␈↓λp␈↓ is a predicate.
␈↓ ↓H␈↓We␈αcertainly␈αmust␈αcompute␈α␈↓αlic[x]␈↓␈α␈↓↓once␈↓.␈αBut␈αas␈α␈↓αg␈↓␈αis␈αdefined,␈αwe␈αwould␈αcompute␈α␈↓αlic[x]␈↓␈α␈↓↓twice␈↓␈αif␈αp␈↓β1␈↓␈αis
␈↓ ↓H␈↓true:␈α∞once␈α∞in␈α∞the␈α
calculation␈α∞of␈α∞p␈↓β1␈↓,␈α∞and␈α∞once␈α
as␈α∞e␈↓β1␈↓.␈α∞Since␈α∞both␈α
calculations␈α∞of␈α∞␈↓αlic[x]␈↓␈α∞will␈α∞give␈α
the
␈↓ ↓H␈↓same value␈↓π 64␈↓, this second calculation is unnecessary. Instead, we could write:
␈↓ ↓H␈↓␈↓ ¬I␈↓αg <= λ[[x] f[lic[x];x]]␈↓
␈↓ ↓H␈↓where:
␈↓ ↓H␈↓␈↓ ¬
␈↓αf <= λ[[u;v][␈↓λp␈↓α[u] → u; .... v ...]]␈↓.
␈↓ ↓H␈↓In␈α
this␈α
scheme␈α
␈↓αlic␈↓␈α
will␈α
only␈α
be␈α
evaluated␈α
once;␈α
its␈α
value␈α
will␈α
be␈α
passed␈α
into␈α
␈↓αf␈↓.␈α
This␈αsolution␈α
requires
␈↓ ↓H␈↓introduction␈α
of␈α
a␈α
new␈α
function␈α
name.␈α
Using␈α
λ-expressions,␈α
in␈α
a␈α
style␈α
called␈α
␈↓↓internal␈α
lambdas␈↓␈αwe
␈↓ ↓H␈↓can improve ␈↓αg␈↓ without adding any new function names to our symbol tables.
␈↓ ↓H␈↓Replace the body of ␈↓αg␈↓ with:
␈↓ ↓H␈↓␈↓ LAM␈↓ ¬ ␈↓αλ[[y][␈↓λp␈↓α[y] → y; ... x ...]][lic[x]]␈↓.
␈↓ ↓H␈↓Call this new function ␈↓αg'␈↓:
␈↓ ↓H␈↓␈↓ αX␈↓αg' <= λ[[x] λ[[y][␈↓λp␈↓α[y] → y; ... x ... ]][lic[x]] ] ␈↓.
␈↓ ↓H␈↓Now␈α⊂when␈α⊃␈↓αg'␈↓␈α⊂is␈α⊃called␈α⊂we␈α⊃evaluate␈α⊂the␈α⊂actual␈α⊃parameter,␈α⊂binding␈α⊃it␈α⊂to␈α⊃␈↓αx␈↓,␈α⊂and␈α⊃evaluate␈α⊂␈↓ LAM␈↓.
␈↓ ↓H␈↓Evaluation␈α
of␈α
␈↓ LAM␈↓␈α
involves␈α
calculation␈α
of␈α
␈↓αlic[x]␈↓␈α∞␈↓↓once␈↓,␈α
binding␈α
the␈α
result␈α
to␈α
␈↓αy␈↓.␈α
We␈α∞then␈α
evaluate
␈↓ ↓H␈↓the␈αbody␈αof␈α
the␈αconditional␈αexpression␈α
as␈αbefore.␈α If␈αp␈↓β1␈↓␈α
␈↓↓is␈↓␈αtrue,␈αthen␈α
this␈αdefinition␈αof␈α
␈↓αg'␈↓␈αinvolves
␈↓ ↓H␈↓one␈α
calculation␈αof␈α
␈↓αlic[x]␈↓␈αand␈α
two␈αtable␈α
look-ups␈α(for␈α
the␈αvalue␈α
of␈α␈↓αy␈↓),␈α
rather␈αthan␈α
the␈αtwo␈α
calculations
␈↓ ↓H␈↓of␈α␈↓αlic[x]␈↓␈αin␈α␈↓αg␈↓.␈α More␈αconventional␈αprogramming␈αlanguages␈αcan␈αobtain␈αthe␈αsame␈αeffect␈αas␈αthis␈αuse␈αof
␈↓ ↓H␈↓internal␈α∂lambdas␈α∂by␈α∂assignment␈α∂of␈α∂␈↓αlic[x]␈↓␈α∞to␈α∂a␈α∂temporary␈α∂variable.␈α∂We␈α∂will␈α∂introduce␈α∞assignment
␈↓ ↓H␈↓statements in LISP in Section 4.2␈↓π 65␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 64␈↓␈αOur␈αcurrent␈αLISP␈αsubset␈αhas␈αno␈αside␈αeffects.␈αThat␈αmeans␈αthere␈αis␈αno␈αway␈αfor␈αa␈αcomputation␈αto
␈↓ ↓H␈↓affect␈α⊂its␈α⊂surrounding␈α⊂environment.␈α⊂The␈α⊂most␈α⊂common␈α⊂construct␈α⊂which␈α⊂has␈α⊂a␈α⊂side-effect␈α⊃is␈α⊂the
␈↓ ↓H␈↓assignment statement.
␈↓ ↓H␈↓␈↓π 65␈↓␈αThis␈α
technique␈αis␈α
also␈αrelated␈α
to␈αthe␈αideas␈α
of␈αcommon␈α
sub-expression␈αrecognition␈α
in␈αcompiling
␈↓ ↓H␈↓algorithms (Section 6.17).
␈↓ ↓H␈↓␈↓↓102 Evaluation␈↓ 23.4␈↓
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. What is the difference between ␈↓αλ[[ ] x*y + y]␈↓ and ␈↓αx*y + y␈↓?
␈↓ ↓H␈↓␈↓ ∧r␈↓↓3.5 Mechanization of Evaluation␈↓
␈↓ ↓H␈↓We␈α
first␈α∞picked␈α
a␈α
representation␈α∞for␈α
LISP␈α
expressions;␈α∞next␈α
we␈α
introduced␈α∞a␈α
precise␈α∞notation␈α
for
␈↓ ↓H␈↓discussing␈αfunctions;␈αand␈αthen␈αwe␈αgave␈αplausibility␈αarguments␈αfor␈αthe␈αexistence␈αof␈αan␈αevaluator␈αfor
␈↓ ↓H␈↓LISP.␈αIt␈αis␈αnow␈αtime␈αto␈αwrite␈αan␈αevaluator␈αfor␈αrepresentations␈αof␈αLISP␈αexpressions.␈α The␈αevaluator
␈↓ ↓H␈↓will␈αbe␈αthe␈αfinal␈αarbiter␈αon␈αthe␈αquestion␈αof␈αthe␈αmeaning␈αof␈αa␈αLISP␈αconstruct.␈αThe␈αevaluator␈αis␈αthus
␈↓ ↓H␈↓a␈α∞very␈α
important␈α∞algorithm.␈α
We␈α∞will␈α∞express␈α
it␈α∞and␈α
its␈α∞related␈α
functions␈α∞in␈α∞as␈α
representation-free
␈↓ ↓H␈↓form␈αas␈αpossible,␈αbut␈αwe␈αwill␈αalways␈αhave␈αour␈αCambridge␈αpolish␈αrepresentation␈αin␈αthe␈αback␈αof␈αour
␈↓ ↓H␈↓minds.
␈↓ ↓H␈↓As␈α
we␈α
have␈α
said,␈α
␈↓αtgmoaf␈↓␈α
and␈α
␈↓αtgmoafr␈↓␈α
(Section 2.7)␈α
are␈α
evaluators␈α
for␈α
subsets␈α
of␈α
LISP.␈α
With␈α
our
␈↓ ↓H␈↓symbol-table␈α∩mechanism␈α∩we␈α⊃could␈α∩now␈α∩extend␈α∩the␈α⊃␈↓↓great-mothers␈↓␈α∩to␈α∩handle␈α∩variable␈α⊃look-ups.
␈↓ ↓H␈↓Rather␈αthan␈αdo␈αthis␈αwe␈αwill␈αmake␈αa␈αtotal␈αrevision␈αof␈αthe␈αstructure␈αof␈αthe␈αevaluators.␈αIn␈αmaking␈αthe
␈↓ ↓H␈↓revision, the following points should be remembered:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α
Expressions␈αto␈α
be␈α
evaluated␈αcan␈α
contain␈αvariables,␈α
both␈α
simple␈αvariables␈α
and␈α
variables␈αnaming
␈↓ ↓H␈↓␈↓ ↓xλ-expressions.␈α∞Therefore,␈α∞evaluation␈α∞must␈α∞be␈α∞done␈α∞with␈α∞respect␈α∞to␈α∞an␈α∞environment␈α∞or␈α∞symbol
␈↓ ↓H␈↓␈↓ ↓xtable.␈α
We␈α
wish␈α
to␈α
recognize␈α
other␈α
(translations␈α
of)␈α
function␈α
names␈α
besides␈α
␈↓αCAR,␈α
CDR,␈αCONS,
␈↓ ↓H␈↓α␈↓ ↓xEQ,␈↓␈αand␈↓α␈αATOM␈↓␈αin␈αour␈αevaluator,␈αbut␈αexplicitly␈αadding␈αnew␈αdefinitions␈αto␈αthe␈αevaluator␈αin␈αthe
␈↓ ↓H␈↓␈↓ ↓xstyle␈α∂of␈α∂the␈α∞recognizers␈α∂for␈α∂the␈α∞five␈α∂primitives␈α∂is␈α∞a␈α∂bad␈α∂idea.␈α∞ That␈α∂would␈α∂require␈α∞rewriting
␈↓ ↓H␈↓␈↓ ↓xsections␈αof␈αthe␈αevaluator␈αevery␈αtime␈αa␈αnew␈αdefinition␈αwas␈αintroduced.␈αAn␈αalternative␈αsolution␈αis
␈↓ ↓H␈↓␈↓ ↓xto␈α
hold␈αthe␈α
definitions␈αin␈α
a␈αsymbol␈α
table.␈αOur␈α
symbol␈αtable␈α
should␈αhold␈α
the␈αfunction␈α
definitions
␈↓ ↓H␈↓␈↓ ↓xand␈α⊃the␈α⊃evaluator␈α⊃should␈α⊃contain␈α∩the␈α⊃general␈α⊃schemes␈α⊃for␈α⊃finding␈α⊃the␈α∩definitions,␈α⊃binding
␈↓ ↓H␈↓␈↓ ↓xvariables␈α
to␈α
values,␈α
and␈αevaluating␈α
the␈α
function␈α
body.␈α
By␈αnow␈α
you␈α
should␈α
be␈α
convinced␈αthat
␈↓ ↓H␈↓␈↓ ↓xthis process is a well-defined task and could be written in LISP.
␈↓ ↓H␈↓␈↓↓2.␈↓␈αAll␈α␈↓↓function␈↓␈αcalls␈α
are␈αto␈αbe␈αevaluated␈α
by-value.␈αHowever,␈αthere␈αare␈α
some␈α␈↓↓special␈αforms␈↓␈αwe␈α
have
␈↓ ↓H␈↓␈↓ ↓xseen␈α∂which␈α⊂are␈α∂not␈α⊂evaluated␈α∂in␈α∂the␈α⊂normal␈α∂manner.␈α⊂ In␈α∂particular,␈α⊂conditional␈α∂expressions,
␈↓ ↓H␈↓␈↓ ↓xquoted␈α⊂expressions,␈α⊂and␈α⊂lambda␈α⊂expressions␈α⊂are␈α⊂handled␈α⊂differently,␈α⊂and␈α⊂the␈α⊂evaluator␈α⊂will
␈↓ ↓H␈↓␈↓ ↓xrecognize these constructs specially.
␈↓ ↓H␈↓The␈αprimary␈αalgorithm␈αin␈αthe␈αevaluator␈αis␈αnamed␈α␈↓αeval␈↓␈αrather␈αthan␈α␈↓αsogm␈↓␈α(Son␈αof␈αGreat␈αMother).␈αIt
␈↓ ↓H␈↓will␈αtake␈αtwo␈α
arguments;␈αthe␈αfirst␈α
will␈αbe␈αa␈αrepresentation␈α
of␈αan␈αexpression␈α
to␈αbe␈αevaluated,␈αand␈α
the
␈↓ ↓H␈↓second␈α
will␈α
be␈α
a␈α
representation␈α
of␈α
a␈α
symbol␈α
table.␈α
The␈α
evaluator␈α
will␈α
recognize␈α
numbers,␈α
and␈αthe
␈↓ ↓H␈↓constants␈α⊂␈↓αT␈↓␈α⊂and␈α⊂␈↓αNIL␈↓,␈α⊂and␈α⊂if␈α⊂presented␈α⊂with␈α⊃a␈α⊂variable,␈α⊂will␈α⊂attempt␈α⊂to␈α⊂find␈α⊂the␈α⊂value␈α⊃of␈α⊂the
␈↓ ↓H␈↓variable in the symbol table using ␈↓αassoc␈↓ (Section 3.3).
␈↓ ↓H␈↓␈↓↓3.5␈↓ πuMechanization of Evaluation 103␈↓
␈↓ ↓H␈↓␈↓αeval␈↓␈α⊃will␈α⊃also␈α∩recognize␈α⊃the␈α⊃special␈α∩forms␈α⊃␈↓αcond␈↓␈α⊃and␈α⊃␈↓αquote␈↓.␈α∩When␈α⊃␈↓αeval␈↓␈α⊃recognizes␈α∩a␈α⊃conditional
␈↓ ↓H␈↓expression␈α∞(represented␈α∞by␈α∞␈↓α(COND␈α∞...)␈↓␈α
),␈α∞the␈α∞body␈α∞of␈α∞the␈α
␈↓αCOND␈↓␈α∞will␈α∞be␈α∞passed␈α∞to␈α∞a␈α
subfunction
␈↓ ↓H␈↓named␈α␈↓αevcond␈↓.␈α␈↓αevcond␈↓␈αembodies␈αthe␈αconditional␈αexpression␈αsemantics␈αas␈αdescribed␈αon␈αpage 19.␈α The
␈↓ ↓H␈↓representation,␈α␈↓α(QUOTE ␈↓λα␈↓α)␈↓,␈αsignifies␈αthe␈αoccurrence␈αof␈αa␈αconstant,␈α␈↓λα␈↓,␈αwhich␈αis␈αsimply␈αreturned.␈α As
␈↓ ↓H␈↓far␈αas␈αthis␈α␈↓αeval␈↓␈αis␈αconcerned,␈αany␈αother␈αexpression␈αis␈αa␈αcall-by-value␈αapplication.␈α The␈αargument-list
␈↓ ↓H␈↓evaluation␈α
is␈α
handled␈α
by␈α
␈↓αevlis␈↓␈α
in␈α
the␈α
authorized␈α
left-to-right␈α
ordering.␈α
This␈α
calculation␈αis␈α
performed
␈↓ ↓H␈↓by␈α
recurring␈α
on␈α
the␈α
list␈α
representing␈α
the␈α∞arguments.␈α
Finally,␈α
we␈α
␈↓↓apply␈↓␈α
the␈α
function␈α
to␈α
the␈α∞list␈α
of
␈↓ ↓H␈↓evaluated arguments. This is done by the function ␈↓αapply␈↓.
␈↓ ↓H␈↓With␈α∂this␈α⊂introduction␈α∂we␈α⊂will␈α∂now␈α⊂write␈α∂a␈α⊂more␈α∂general␈α⊂evaluator␈α∂which␈α⊂will␈α∂handle␈α⊂a␈α∂larger
␈↓ ↓H␈↓subset of LISP than the ␈↓αtgm␈↓s.
␈↓ ↓H␈↓α␈↓Here's the new ␈↓αeval␈↓:␈↓α
␈↓ ↓H␈↓αeval <= λ[[exp;environ]
␈↓ ↓H␈↓α␈↓ αh[isvar[exp] → lookup[exp;environ];
␈↓ ↓H␈↓α␈↓ αh isconst[exp] → denote[exp];
␈↓ ↓H␈↓α␈↓ αh iscond[exp] → evcond[arg␈↓βc␈↓α[exp];environ];
␈↓ ↓H␈↓α␈↓ αh isfunc+args[exp] → apply[␈↓ ¬Hfunc[exp];
␈↓ ↓H␈↓α␈↓ αh␈↓ ¬Hevlis[arglist[exp];environ];
␈↓ ↓H␈↓α␈↓ αh␈↓ ¬Henviron] ]]
␈↓ ↓H␈↓α␈↓and:␈↓α
␈↓ ↓H␈↓αlookup <=λ[[var;env] value[assoc[var;env]]]
␈↓ ↓H␈↓αdenote <= λ[[exp]
␈↓ ↓H␈↓α␈↓ αh[isnumber[exp] → exp;
␈↓ ↓H␈↓α␈↓ αh istruth[exp] → exp;
␈↓ ↓H␈↓α␈↓ αh isfalse[exp] → exp;
␈↓ ↓H␈↓α␈↓ αh isSexpr[exp] → rep[exp];
␈↓ ↓H␈↓α␈↓ αh is-λ[exp] → exp ]]
␈↓ ↓H␈↓where:
␈↓ ↓H␈↓␈↓αrep␈↓␈α∂knows␈α∂how␈α∂to␈α∞extract␈α∂the␈α∂S-expr␈α∂from␈α∞the␈α∂representation.␈α∂In␈α∂our␈α∞scheme␈α∂the␈α∂selector␈α∂␈↓αrep␈↓␈α∞is
␈↓ ↓H␈↓␈↓ αλgiven by ␈↓αcadr␈↓.
␈↓ ↓H␈↓The␈α∪other␈α∀selectors,␈α∪constructors␈α∀and␈α∪recognizers␈α∪which␈α∀relate␈α∪this␈α∀abstract␈α∪definition␈α∀to␈α∪our
␈↓ ↓H␈↓particular S-expression representation are grouped with ␈↓αapply␈↓ on page 105.
␈↓ ↓H␈↓αevcond <= λ[[e;environ]
␈↓ ↓H␈↓α␈↓ αh[eval[ante[first[e]];environ] → eval[conseq[first[e]];environ];
␈↓ ↓H␈↓α␈↓ αh ␈↓
t␈↓α → evcond[rest[e];environ] ]]
␈↓ ↓H␈↓␈↓↓104 Evaluation␈↓ 43.5␈↓
␈↓ ↓H␈↓α␈↓and,␈↓α
␈↓ ↓H␈↓αevlis <= λ[[e;environ]␈↓ βX[null[e] → ( );
␈↓ ↓H␈↓α␈↓ βX ␈↓
t␈↓α → concat[␈↓ ∧xeval[first[e];environ];
␈↓ ↓H␈↓α␈↓ βX␈↓ ∧xevlis[rest[e];environ]] ]]
␈↓ ↓H␈↓The␈α⊂subfunctions,␈α∂␈↓αevcond␈↓␈α⊂and␈α⊂␈↓αevlis␈↓,␈α∂are␈α⊂simple.␈α∂ ␈↓αevcond␈α⊂␈↓you've␈α⊂seen␈α∂before␈α⊂in␈α∂␈↓αtgmoafr␈↓␈α⊂in␈α⊂a␈α∂less
␈↓ ↓H␈↓abstract␈α∞form;␈α∞␈↓αevlis␈↓␈α∞constructs␈α∞a␈α∞new␈α∞list␈α∞consisting␈α∞of␈α∞the␈α∞results␈α∞of␈α∞evaluating␈α∞the␈α∞elements␈α∂of␈α∞␈↓αe␈↓
␈↓ ↓H␈↓from␈α
left␈α
to␈α
right,␈α
using␈α
the␈α
symbol␈α
table,␈α
␈↓αenviron␈↓,␈α
where␈α
necessary.␈α
Since␈α
␈↓αevcond␈↓␈α
and␈α
␈↓αevlis␈↓␈αare␈α
LISP
␈↓ ↓H␈↓functions,␈α␈↓↓they␈↓␈αare␈αsubject␈αto␈αthe␈αleft-to-right␈αevaluation␈αrule.␈αThus␈α␈↓αevlis␈↓␈αembodies␈αthe␈αleft-to-right
␈↓ ↓H␈↓rule.␈α∂ If␈α∂␈↓αevlis␈↓␈α∂were␈α∂evaluated␈α∂under␈α⊂a␈α∂right-to-left␈α∂rule␈α∂then␈α∂␈↓αevlis␈↓␈α∂would␈α∂evaluate␈α⊂expressions␈α∂in
␈↓ ↓H␈↓right-to-left␈αorder.␈α It␈αis␈αpossible␈αto␈αwrite␈αa␈αversion␈αof␈α␈↓αevlis␈↓␈αwhich␈αonly␈αdepends␈αon␈αbeing␈αevaluated
␈↓ ↓H␈↓␈↓ CBV␈↓, and which does embody the left-to-right rule:
␈↓ ↓H␈↓αevlis <= λ[[e;environ]␈↓ βh[null[e] → ( );
␈↓ ↓H␈↓α␈↓ βh ␈↓
t␈↓α → λ[[x] concat[x;evlis[rest[e];environ]]]
␈↓ ↓H␈↓α␈↓ βh␈↓ ∧x[eval[first[e];environ]] ]]
␈↓ ↓H␈↓The␈αfunction␈α␈↓αapply␈↓␈αtakes␈αthree␈αarguments:␈αa␈αrepresentation␈αof␈αa␈αfunction,␈αa␈αrepresentation␈αof␈αa␈αlist
␈↓ ↓H␈↓of␈α⊂evaluated␈α⊂arguments,␈α∂and␈α⊂a␈α⊂representation␈α∂of␈α⊂a␈α⊂symbol␈α∂table.␈α⊂␈↓αapply␈↓␈α⊂explicitly␈α⊂recognizes␈α∂the
␈↓ ↓H␈↓representations␈αof␈αthe␈αfive␈αprimitive␈αfunctions␈α␈↓αCAR,␈αCDR,␈αCONS,␈αEQ,␈α␈↓and␈↓α␈αATOM␈↓.␈αIf␈αthe␈αfunction
␈↓ ↓H␈↓name␈α∩is␈α⊃a␈α∩variable,␈α⊃the␈α∩definition␈α⊃is␈α∩located␈α⊃in␈α∩the␈α⊃symbol␈α∩table␈α⊃by␈α∩␈↓αeval␈↓␈α⊃and␈α∩applied␈α∩to␈α⊃the
␈↓ ↓H␈↓arguments.␈α
Otherwise␈α
the␈α
function␈α∞must␈α
be␈α
a␈α
λ-expression.␈α∞ This␈α
is␈α
where␈α
things␈α∞get␈α
interesting.
␈↓ ↓H␈↓We␈α
know␈α
we␈α∞must␈α
evaluate␈α
the␈α
body␈α∞of␈α
the␈α
λ-expression␈α
after␈α∞binding␈α
the␈α
formal␈α∞parameters␈α
of
␈↓ ↓H␈↓the␈αλ-expression␈αto␈αthe␈αevaluated␈αarguments.␈α We␈α
add␈αvariable-value␈αpairs␈αto␈αthe␈αsymbol␈αtable.␈α
We
␈↓ ↓H␈↓will␈α
define␈α∞a␈α
subfunction,␈α
␈↓αmkenv␈↓,␈α∞to␈α
perform␈α∞the␈α
binding.␈α
Then␈α∞all␈α
that␈α∞is␈α
left␈α
to␈α∞do␈α
is␈α∞give␈α
the
␈↓ ↓H␈↓function body and the new symbol table to ␈↓αeval␈↓.
␈↓ ↓H␈↓α␈↓Here is ␈↓αapply␈↓:␈↓α
␈↓ ↓H␈↓αapply <= λ[[fn;args,environ]
␈↓ ↓H␈↓α␈↓ β([iscar[fn] → car[arg␈↓β1␈↓α[args]];
␈↓ ↓H␈↓α␈↓ β( iscons[fn] → cons[arg␈↓β1␈↓α[args];arg␈↓β2␈↓α[args]];
␈↓ ↓H␈↓α␈↓ β( ... ...
␈↓ ↓H␈↓α␈↓ β( isvar[fn] → apply[eval[fn;environ];args;environ];
␈↓ ↓H␈↓α␈↓ β( islambda[fn] → eval[␈↓ ¬8body[fn];
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬8mkenv[vars[fn];args;environ]] ]]
␈↓ ↓H␈↓αmkenv <= λ[[vars;vals;environ] pairlis[vars;vals;environ]]
␈↓ ↓H␈↓αpairlis <= λ[[vars;vals;environ]
␈↓ ↓H␈↓α␈↓ β([null[vars] → environ;
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → concat[␈↓ ∧8mkent[first[vars];first[vals]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧8pairlis[␈↓ ¬_rest[vars];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧8␈↓ ¬_rest[vals];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧8␈↓ ¬_environ]] ]]
␈↓ ↓H␈↓␈↓↓3.5␈↓ πuMechanization of Evaluation 105␈↓
␈↓ ↓H␈↓The␈α_functions␈α_and␈α_predicates␈α_which␈α→will␈α_relate␈α_these␈α_abstract␈α_definitions␈α_to␈α→our␈α_specific
␈↓ ↓H␈↓S-expression representation of LISP constructs are:
␈↓ ↓H␈↓↓␈↓ αλRecognizers␈↓ ¬xSelectors␈↓ λ8Constructor
␈↓ ↓H␈↓αiscar <= λ[[x] eq[x;CAR]]␈↓ ¬xfunc <= λ[[x] first[x]]␈↓ λ8mkent <= λ[[x;y] cons[x;y]]
␈↓ ↓H␈↓αisSexpr <= λ[[x] eq[first[x];QUOTE]]␈↓ ¬xarglist <= λ[[x] rest[x]]
␈↓ ↓H␈↓αistruth <= λ[[x] eq[x;T]]␈↓ ¬xbody <= λ[[x] third[x]]
␈↓ ↓H␈↓αislambda <= λ[[x] eq[first[x];LAMBDA]]␈↓ ¬xvars <= λ[[x] second[x]]
␈↓ ↓H␈↓αisfun+args <= λ[[x] ␈↓
t␈↓α]␈↓ ¬xargs␈↓βc␈↓α <= λ[[x] rest[x]]
␈↓ ↓H␈↓α␈↓ αλ␈↓ ¬xarg␈↓β1␈↓α <= λ[[x] first[x]]
␈↓ ↓H␈↓α␈↓ αλ␈↓ ¬xarg␈↓β2␈↓α <= λ[[x] second[x]]
␈↓ ↓H␈↓α␈↓ αλ␈↓ ¬xante <= λ[[x] first[x]]
␈↓ ↓H␈↓α␈↓ αλ␈↓ ¬xconseq <= λ[[x] second[x]]
␈↓ ↓H␈↓α␈↓ αλ␈↓ ¬xrep <= λ[[x] second[x]]
␈↓ ↓H␈↓The␈α
innovation␈α
is␈α
in␈α
the␈α
λ-binding␈αprocess.␈α
Another␈α
application␈α
of␈α
the␈α
left-to-right␈αproperty␈α
occurs
␈↓ ↓H␈↓here,␈α∂within␈α∞␈↓αapply␈↓,␈α∂in␈α∞the␈α∂symbol␈α∂table␈α∞search␈α∂and␈α∞construction␈α∂process.␈α∞Notice␈α∂that␈α∂␈↓αlookup␈↓␈α∞uses
␈↓ ↓H␈↓␈↓αassoc␈↓␈α⊂to␈α⊂look␈α⊂from␈α⊂left␈α⊃to␈α⊂right␈α⊂for␈α⊂the␈α⊂latest␈α⊂binding␈α⊃of␈α⊂a␈α⊂variable.␈α⊂Thus␈α⊂the␈α⊃function␈α⊂which
␈↓ ↓H␈↓␈↓↓augments␈↓␈α⊃the␈α∩table␈α⊃must␈α∩add␈α⊃the␈α⊃latest␈α∩binding␈α⊃to␈α∩the␈α⊃␈↓↓front␈↓.␈α⊃New␈α∩bindings␈α⊃occur␈α∩when␈α⊃the
␈↓ ↓H␈↓function␈α∂␈↓αmkenv␈↓,␈α∂using␈α∂␈↓αpairlis␈↓,␈α∂builds␈α∂an␈α∂augmented␈α∂symbol␈α∂table␈α∂with␈α∂the␈α∂λ-variables␈α∂bound␈α∂to
␈↓ ↓H␈↓their␈α∃evaluated␈α∃arguments.␈α⊗The␈α∃functions␈α∃␈↓αlookup␈↓␈α∃and␈α⊗␈↓αmkenv␈↓␈α∃operate␈α∃together.␈α∃We␈α⊗will␈α∃see
␈↓ ↓H␈↓representations␈αof␈αthese␈αfunctions␈αother␈αthan␈α␈↓αassoc␈↓␈αand␈α␈↓αpairlis␈↓.␈αThe␈αactual␈αsearch␈αand␈αconstruction
␈↓ ↓H␈↓operations␈α∞will␈α∂change,␈α∞but␈α∂the␈α∞critical␈α∂relationship␈α∞that␈α∂␈↓αmkenv␈↓␈α∞always␈α∂builds␈α∞a␈α∂table␈α∞compatible
␈↓ ↓H␈↓with the search strategy of ␈↓αlookup␈↓ will be maintained.
␈↓ ↓H␈↓To␈αsummarize␈αthen:␈α
the␈αevaluation␈αof␈αan␈α
expression␈α␈↓αf[a␈↓β1␈↓α; ... ;a␈↓βn␈↓α]␈↓,␈αwhere␈α
the␈α␈↓αa␈↓βi␈↓'s␈αare␈αS-exprs,␈α
consists
␈↓ ↓H␈↓in␈α∞applying␈α
␈↓αeval␈↓␈α∞to␈α∞the␈α
␈↓
R␈↓-translation,␈α∞␈↓α(␈↓
R␈↓∞(␈↓α f ␈↓∞)␈↓α ␈↓
R␈↓∞(␈↓α a␈↓β1 ␈↓∞)␈↓α ... ␈↓
R␈↓∞(␈↓α a␈↓βn ␈↓∞)␈↓α).␈↓␈α∞This␈α
behavior␈α∞is␈α∞again␈α
an
␈↓ ↓H␈↓example␈α
of␈α
the␈αdiagrams␈α
of␈α
page 52.␈α
In␈αits␈α
most␈α
simple␈α
terms,␈αwe␈α
mapped␈α
LISP␈α
evaluation␈αonto␈α
the
␈↓ ↓H␈↓LISP␈α␈↓αeval␈↓␈αfunction;␈α
mapped␈αLISP␈αexpressions␈α
onto␈αS-expressions;␈αand␈α
executed␈α␈↓αeval␈↓.␈αNotice␈αthat␈α
in
␈↓ ↓H␈↓this␈α∩case␈α∩we␈α⊃do␈α∩not␈α∩reinterpret␈α∩the␈α⊃output␈α∩since␈α∩the␈α∩structure␈α⊃of␈α∩the␈α∩representation␈α∩does␈α⊃this
␈↓ ↓H␈↓implicitly. We have commented on the efficacy of this already on page 97.
␈↓ ↓H␈↓The␈α
specification␈α
of␈α
the␈α
evaluation␈α∞of␈α
LISP␈α
expressions␈α
using␈α
␈↓αeval␈↓␈α∞and␈α
␈↓αapply␈↓␈α
is␈α
one␈α
of␈α∞the␈α
most
␈↓ ↓H␈↓interesting developments of computer science.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I.␈αCompare␈α
our␈αversion␈αof␈α
␈↓αeval␈↓␈αand␈α␈↓αapply␈↓␈α
with␈αthe␈α
version␈αgiven␈αin␈α
[McC 65].␈αThough␈αthe␈α
current
␈↓ ↓H␈↓version␈αis␈αmuch␈αmore␈αreadable,␈α
how␈αmuch␈αof␈αit␈α␈↓↓still␈↓␈α
depends␈αon␈αthe␈αrepresentation␈αwe␈αchose?␈α
That
␈↓ ↓H␈↓is, how abstract is it really?
␈↓ ↓H␈↓␈↓↓106 Evaluation␈↓ 43.5␈↓
␈↓ ↓H␈↓II. Complete the specification of the selectors, constructors, and recognizers.
␈↓ ↓H␈↓␈↓ ¬A␈↓↓3.6 Examples of ␈↓αeval␈↓↓␈↓α
␈↓ ↓H␈↓We␈α
will␈α
demonstrate␈α
the␈α∞inner␈α
workings␈α
of␈α
the␈α
evaluation␈α∞algorithm␈α
on␈α
a␈α
couple␈α
of␈α∞samples␈α
and
␈↓ ↓H␈↓will␈αdescribe␈αthe␈αflow␈αof␈αcontrol␈αin␈αthe␈αexecution␈αin␈αa␈αcouple␈αof␈αdifferent␈αways.␈αThe␈αexamples␈αwill
␈↓ ↓H␈↓be␈α∞done␈α
in␈α∞terms␈α
of␈α∞the␈α∞image␈α
of␈α∞the␈α
␈↓
R␈↓-mapping␈α∞rather␈α∞than␈α
being␈α∞done␈α
abstractly.␈α∞We␈α∞do␈α
this
␈↓ ↓H␈↓since␈αthe␈αstructure␈αof␈αan␈αactual␈αLISP␈αevaluator␈αwill␈αuse␈αthis␈αrepresentation␈↓π 66␈↓.␈α It␈αis␈αimportant␈αthat
␈↓ ↓H␈↓you␈α⊃diligently␈α⊃study␈α⊃the␈α∩sequence␈α⊃of␈α⊃events␈α⊃in␈α⊃the␈α∩execution␈α⊃of␈α⊃the␈α⊃evaluator.␈α⊃The␈α∩process␈α⊃is
␈↓ ↓H␈↓detailed and tedious but it must be done.
␈↓ ↓H␈↓Let's evaluate ␈↓αf[2;3]␈↓ where ␈↓αf <= λ[[x;y] x␈↓π2␈↓α + y].␈↓ That is, evaluate:
␈↓ ↓H␈↓␈↓ βu␈↓αeval[ ␈↓
R␈↓∞(␈↓α f[2;3] ␈↓∞)␈↓α; ␈↓
R␈↓∞(␈↓α{ <f, λ[[x;y] +[↑[x;2]; y]]> }␈↓∞)␈↓α]␈↓.
␈↓ ↓H␈↓After appropriate translation this is equivalent to evaluating:
␈↓ ↓H␈↓␈↓ β+␈↓αeval[(F 2 3); ((F . (LAMBDA (X Y) (PLUS (EXPT X 2) Y))))]␈↓
␈↓ ↓H␈↓␈↓↓Notes:␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓␈α␈↓α((F␈α.␈α(LAMBDA␈α(X␈αY)␈α...␈α)))␈α=␈α((F␈α
LAMBDA␈α(X␈αY)␈α...␈α))␈α␈↓␈αThis␈αis␈αmentioned␈αbecause␈αmost␈α
LISP
␈↓ ↓H␈↓␈↓ ↓ximplementations will print the latter even if you write the former.
␈↓ ↓H␈↓␈↓↓2.␈↓␈α
Since␈α
the␈α
symbol␈α
table␈α␈↓α((F␈α
...))␈↓␈α
occurs␈α
so␈α
frequently␈α
in␈αthe␈α
following␈α
trace,␈α
we␈α
will␈α
abbreviate␈αit␈α
as
␈↓ ↓H␈↓␈↓ ↓x␈↓αst␈↓.␈α
We␈α∞have␈α
no␈α
mechanism␈α∞yet␈α
for␈α∞permanently␈α
increasing␈α
the␈α∞repertoire␈α
of␈α∞known␈α
functions.
␈↓ ↓H␈↓␈↓ ↓xWe must therefore resort to subterfuge and initialize the symbol table to get ␈↓αf␈↓ defined.
␈↓ ↓H␈↓␈↓↓3.␈↓␈α∂For␈α∂this␈α∂example␈α∂we␈α∂must␈α∂assume␈α∂that␈α∂+␈α∂and␈α∂↑␈α∂(exponentiation)␈α∂are␈α∂known␈α∂functions.␈α∞ Thus
␈↓ ↓H␈↓␈↓ ↓x␈↓αapply␈↓ would have to contain recognizers for ␈↓αPLUS␈↓ and ␈↓αTIMES␈↓:
␈↓ ↓H␈↓α ... atom[fn] → [isplus[fn] → +[arg␈↓β1␈↓α[args];arg␈↓β2␈↓α[args]];
␈↓ ↓H␈↓α isexpt[fn] → ↑[arg␈↓β1␈↓α[args];arg␈↓β2␈↓α[args]];
␈↓ ↓H␈↓α ... ]
␈↓ ↓H␈↓α ...
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 66␈↓ Recall that we will be programming in the ␈↓
R␈↓-image.
␈↓ ↓H␈↓␈↓↓3.6␈↓ ∩Examples of ␈↓αeval␈↓↓ 107␈↓α
␈↓ ↓H␈↓So ␈↓αeval[(F 2 3);st]
␈↓ ↓H␈↓α␈↓ αX= apply[func[(F 2 3)]; evlis[arglist[(F 2 3)];st];st]
␈↓ ↓H␈↓α␈↓ αX= apply[F;evlis[(2 3);st];st]
␈↓ ↓H␈↓α␈↓ αX= apply[F;(2 3);st]
␈↓ ↓H␈↓α␈↓ αX= apply[eval[F;st];(2 3);st]
␈↓ ↓H␈↓α␈↓ αX= apply[(LAMBDA (X Y) (PLUS (EXPT X 2) Y)); (2 3);st]
␈↓ ↓H␈↓α␈↓ αX= eval[body[(LAMBDA (X Y) (PLUS (EXPT X 2) Y))];
␈↓ ↓H␈↓α␈↓ αX mkenv[vars[(LAMBDA (X Y) (PLUS (EXPT X 2) Y))];(2 3);st]]
␈↓ ↓H␈↓α␈↓ αX= eval[(PLUS (EXPT X 2) Y);pairlis[(X Y);(2 3);st]]
␈↓ ↓H␈↓α␈↓ αX= eval[(PLUS (EXPT X 2) Y);((X . 2)(Y . 3)(F LAMBDA (X Y) ...))]
␈↓ ↓H␈↓α␈↓ αX= apply [PLUS; evlis[((EXPT X 2) Y);((X . 2)(Y . 3)..)];((X . 2)...)]
␈↓ ↓H␈↓α␈↓ αX ␈↓Let's do a little of:␈↓α evlis[((EXPT X 2) Y);((X . 2)(Y . 3)...)]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= concat[eval[(EXPT X 2);((X . 2)(Y . 3) ...)];
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H evlis[(Y);((X . 2) ...)]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= concat[apply[EXPT;evlis[(X 2);((X . 2)...)];((X . 2) ...]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H evlis[(Y); ...]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= concat[apply[EXPT;(2 2);((X . 2) ...];evlis[(Y); ...]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= concat[↑[arg␈↓β1␈↓α[(2 2)];arg␈↓β2␈↓α[(2 2)]];evlis[(Y); ... ]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= concat[↑[2;2];evlis[(Y); ... ]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= concat[4;evlis[(Y);((X . 2)(Y . 3) ....)]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= concat[4;concat[eval[Y;((X .2) ...)]; evlis[( );(( ...))]]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= concat[4;concat[3;( )]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧H= (4 3)␈↓
␈↓ ↓H␈↓Now back to apply:
␈↓ ↓H␈↓α␈↓ αX= apply[PLUS;(4 3);((X . 2)(Y . 3) ... )]
␈↓ ↓H␈↓α␈↓ αX= +[4;3]
␈↓ ↓H␈↓α␈↓ αX= 7␈↓
␈↓ ↓H␈↓It␈α∂should␈α∂now␈α∂be␈α∂clear␈α∂that␈α∂␈↓αeval␈↓␈α∂and␈α∂friends␈α∂␈↓↓do␈↓␈α∂perform␈α∂as␈α∂you␈α∂would␈α∂expect,␈α∂at␈α∂least␈α∂for␈α∂this
␈↓ ↓H␈↓example.␈α It␈αis␈αnot␈αclear␈αthat␈αa␈αsimpler␈αscheme␈αmight␈αnot␈αdo␈αas␈αwell.␈α In␈αparticular,␈αthe␈αcomplexity
␈↓ ↓H␈↓of␈α∞the␈α
symbol␈α∞table␈α
mechanism␈α∞which␈α
we␈α∞claimed␈α
was␈α∞so␈α
important␈α∞has␈α
not␈α∞been␈α∞exploited.␈α
The
␈↓ ↓H␈↓next example will show that a scheme like ours is necessary to keep track of variable bindings.
␈↓ ↓H␈↓␈↓↓108 Evaluation␈↓ 53.6␈↓
␈↓ ↓H␈↓Let's sketch the evaluation of ␈↓αfact[3]␈↓ where:
␈↓ ↓H␈↓␈↓ ∧@␈↓αfact <= λ[[x][x = 0 → 1;␈↓
t␈↓α → *[x;fact[x-1]]]];␈↓
␈↓ ↓H␈↓that is, ␈↓αeval[(FACT 3);st] ␈↓where ␈↓αst␈↓ names the initial symbol table:
␈↓ ↓H␈↓α((FACT .␈↓ αH(LAMBDA (X) (COND␈↓ ¬λ((ZEROP X) 1)
␈↓ ↓H␈↓α␈↓ αH␈↓ ¬λ(T (TIMES X (FACT (SUB1 X)))))))).␈↓␈↓π 67␈↓.
␈↓ ↓H␈↓In␈α
this␈α
example␈α
we␈α
will␈α
assume␈α
that␈α
the␈α
binary␈α
function␈α
*,␈α
the␈α
unary␈α
predicate␈α
␈↓αzerop <= λ[[x] x = 0]␈↓
␈↓ ↓H␈↓and␈αunary␈αfunction␈α␈↓α␈αsub1 <= λ[[x] x-1]␈↓␈αare␈α
known␈αand␈αare␈αrecognized␈αin␈αthe␈αevaluator␈α
as␈α␈↓αTIMES,
␈↓ ↓H␈↓αZEROP␈↓ and ␈↓αSUB1␈↓ respectively.
␈↓ ↓H␈↓Then␈↓α eval[(FACT 3);st]
␈↓ ↓H␈↓α␈↓ αX= apply[FACT;evlis[(3);st];st]
␈↓ ↓H␈↓α␈↓ αX= apply[(LAMBDA (X) (COND ...));(3);st]
␈↓ ↓H␈↓α␈↓ αX= eval[(COND ((ZEROP X) 1) (T ( ...)));((X . 3) . st)]
␈↓ ↓H␈↓α␈↓ αX= evcond[(((ZEROP X) 1) (T (TIMES X (FACT (SUB1 X)))));((X . 3) . st)]
␈↓ ↓H␈↓α␈↓(Now, let ␈↓αst1␈↓ be␈↓α ((X . 3) . st) )
␈↓ ↓H␈↓α␈↓ αX= eval[(TIMES X (FACT (SUB1 X))); st1]
␈↓ ↓H␈↓α␈↓ αX= apply[TIMES;evlis[(X (FACT (SUB1 X))); st1];st1]
␈↓ ↓H␈↓α␈↓ αX= apply[TIMES;concat[3;evlis[((FACT (SUB1 X))); st1]];st1]
␈↓ ↓H␈↓α␈↓Now things get a little interesting inside ␈↓αevlis:
␈↓ ↓H␈↓α␈↓ αXevlis[((FACT (SUB1 X)));st1]
␈↓ ↓H␈↓α␈↓ αX␈↓ βx= concat[eval[(FACT (SUB1 X)); st1];( )]
␈↓ ↓H␈↓α␈↓ αX␈↓ βx␈↓ and ␈↓α eval[(FACT (SUB1 X));st1]
␈↓ ↓H␈↓α␈↓ αX␈↓ βx␈↓ ¬_= apply[FACT;evlis[((SUB1 X));st1];st1]
␈↓ ↓H␈↓α␈↓ αX␈↓ βx␈↓ ¬_= apply[FACT; (2);st1]
␈↓ ↓H␈↓α␈↓ αX␈↓ βx␈↓ ¬_= apply[(LAMBDA (X) (COND ...));(2);st1]
␈↓ ↓H␈↓α␈↓ αX␈↓ βx␈↓ ¬_= eval[(COND ((ZEROP X) 1) ...));((X . 2) . st1)]
␈↓ ↓H␈↓α␈↓ αX␈↓ βx␈↓ ¬_...
␈↓ ↓H␈↓Within␈αthis␈αlatest␈αcall␈α
on␈α␈↓αeval␈↓␈αthe␈αsymbol-table-searching␈αfunction,␈α
␈↓αlookup␈↓,␈αwill␈αfind␈αthe␈αpair␈α
␈↓α(X . 2)␈↓
␈↓ ↓H␈↓when␈α
looking␈α
for␈α
the␈α
value␈α
of␈α
␈↓αx␈↓.␈α
This␈α
is␈αas␈α
it␈α
should␈α
be.␈α
But␈α
notice␈α
also␈α
that␈α
the␈α
older␈αbinding,
␈↓ ↓H␈↓␈↓α(X . 3)␈↓,␈α∞is␈α∞still␈α∞around␈α∞in␈α∂the␈α∞symbol␈α∞table␈α∞␈↓αst1␈↓,␈α∞and␈α∂will␈α∞become␈α∞accessible␈α∞once␈α∞we␈α∂complete␈α∞this
␈↓ ↓H␈↓latest␈α
call␈α
on␈α
␈↓αeval␈↓.␈α
It␈α
will␈α
become␈α
accessible␈α
because␈α
this␈α
earlier␈α
manifestation␈α
of␈α
the␈α
table␈α
was␈α
saved
␈↓ ↓H␈↓by␈αthe␈αλ-binding␈α
process␈αas␈αwe␈αentered␈α
the␈αinner␈αcall␈α
on␈α␈↓αeval␈↓;␈αas␈αwe␈α
leave␈αthis␈αinner␈αevaluation,␈α
the
␈↓ ↓H␈↓previous incarnation of the table is restored.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 67␈↓␈α∞We␈α∞have␈α∂split␈α∞the␈α∞␈↓αCOND␈↓␈α∞across␈α∂several␈α∞lines␈α∞in␈α∞an␈α∂indented␈α∞fashion␈α∞to␈α∂improve␈α∞readibility.
␈↓ ↓H␈↓Such␈αtechniques␈αare␈αcommon␈αin␈αLISP.␈αThe␈αidea␈αis␈αcalled␈α"pretty printing"␈αand␈αis␈αdiscussed␈αfurther
␈↓ ↓H␈↓on page 254 and in Section 9.2.
␈↓ ↓H␈↓␈↓↓3.6␈↓ ∩Examples of ␈↓αeval␈↓↓ 109␈↓α
␈↓ ↓H␈↓As the computation continues, the current symbol table appears as follows:
␈↓ ↓H␈↓α␈↓ ∧B((FACT LAMBDA (X) (COND ...))) = st,
␈↓ ↓H␈↓α␈↓ ¬Z((X . 3) . st) = st␈↓λ'␈↓α,
␈↓ ↓H␈↓α␈↓ ¬O((X . 2) . st␈↓λ'␈↓α) = st␈↓λ''␈↓α,
␈↓ ↓H␈↓α␈↓ ¬G((X . 1) . st␈↓λ''␈↓α) = st␈↓λ'''␈↓α,
␈↓ ↓H␈↓α␈↓ ¬m((X . 0) . st␈↓λ'''␈↓α).
␈↓ ↓H␈↓Thus␈αeach␈αnew␈αlevel␈αof␈αthe␈α
table␈αbuilds␈αon␈αthe␈αprior␈α␈↓αst␈↓;␈αeach␈α
prior␈α␈↓αst␈↓␈αis␈αsaved␈αin␈αthe␈αfollowing␈α
line
␈↓ ↓H␈↓from ␈↓αapply␈↓ (page 104):
␈↓ ↓H␈↓α␈↓ β\islambda[fn] → eval[body[fn];mkenv[vars[fn];args;environ].
␈↓ ↓H␈↓The␈α
call␈α
on␈α
␈↓αeval␈↓␈α
is␈α
performed␈α
with␈α
the␈αaugmented␈α
table;␈α
when␈α
we␈α
leave␈α
that␈α
inner␈α
␈↓αeval␈↓␈α
we␈αreturn␈α
to
␈↓ ↓H␈↓an environment which contains the prior ␈↓αst␈↓.
␈↓ ↓H␈↓We␈α
claim␈α
that␈αusing␈α
␈↓αmkenv␈↓␈α
to␈αconcat␈α
the␈α
new␈αbindings␈α
onto␈α
the␈αfront␈α
of␈α
the␈αsymbol␈α
table␈α
as␈αwe␈α
call
␈↓ ↓H␈↓␈↓αeval␈↓␈α
does␈α
the␈αright␈α
thing.␈α
The␈αtricky␈α
part␈α
is␈αthat␈α
when␈α
we␈αleave␈α
that␈α
particular␈αcall␈α
on␈α
␈↓αeval␈↓,␈αthe␈α
old
␈↓ ↓H␈↓table␈α∂is␈α∂automatically␈α∞restored␈α∂by␈α∂the␈α∞recursion␈α∂mechanism.␈α∂ That␈α∞is,␈α∂if␈α∂␈↓αst␈↓␈α∞is␈α∂the␈α∂current␈α∞symbol
␈↓ ↓H␈↓table␈αthen␈α␈↓αconcat␈↓-ing␈αthings␈αonto␈αthe␈αfront␈αof␈α␈↓αst␈↓␈αdoesn't␈αchange␈α␈↓αst␈↓,␈αbut␈αif␈αwe␈αcall␈α␈↓αeval␈↓␈αor␈α␈↓αapply␈↓␈αwith
␈↓ ↓H␈↓a symbol table of say:
␈↓ ↓H␈↓␈↓ ∧y␈↓αconcat[(X . 2);concat[(X . 3); st]] ␈↓
␈↓ ↓H␈↓then in ␈↓↓that␈↓ call on ␈↓αeval␈↓ or ␈↓αapply␈↓ we have access to ␈↓αx = 2␈↓, not ␈↓αx = 3␈↓.
␈↓ ↓H␈↓In␈α∞this␈α∞representation,␈α∞the␈α
search␈α∞function␈α∞␈↓αlookup␈↓␈α∞always␈α∞proceeds␈α
from␈α∞left␈α∞to␈α∞right␈α∞through␈α
the
␈↓ ↓H␈↓table␈αand,␈α
since␈αthe␈αtable␈α
entry␈αfunction␈α␈↓αmkenv␈↓␈α
always␈α␈↓αconcat␈↓s␈αpairs␈α
onto␈αthe␈αleft␈α
of␈αthe␈αtable␈α
before
␈↓ ↓H␈↓␈↓αeval␈↓ is called, we will get the expected binding of the variables.
␈↓ ↓H␈↓The␈αstructure␈α
of␈α␈↓αmkenv␈↓␈α
should␈αbe␈αanalyzed␈α
further:␈αit␈α
takes␈αa␈αformal␈α
parameter␈αlist,␈α
an␈αevaluated
␈↓ ↓H␈↓actual␈αparameter␈αlist,␈αand␈αan␈αenvironment,␈αas␈αits␈αarguments;␈αit␈αallocates␈αa␈αnew␈αblock␈αto␈αcontain␈αthe
␈↓ ↓H␈↓name-value␈α
pairs␈α
and␈α
proceeds␈α
to␈α
send␈α
each␈α
name-value␈α
pair␈α
to␈α
its␈α
proper␈α
slot␈α
in␈α
the␈α
block.␈α
The
␈↓ ↓H␈↓value␈α∞of␈α∞␈↓αmkenv␈↓␈α∞is␈α∞the␈α∞newly␈α∞constructed␈α∞environment␈α∞formed␈α∞by␈α∞linking␈α∞the␈α∞new␈α∞block␈α∞onto␈α∞the
␈↓ ↓H␈↓front␈αof␈αthe␈αold␈αenvironment.␈αIt␈αturns␈αout␈αthat␈α␈↓αpairlis␈↓␈αis␈αable␈αto␈αcombine␈αthe␈αaction␈αof␈αmaking␈αthe
␈↓ ↓H␈↓new block and filling the slots.
␈↓ ↓H␈↓A more accurate picture of the abstract behavior of ␈↓αmkenv␈↓ is:
␈↓ ↓H␈↓αmkenv <= λ[[vars;vals;env] mkenv␈↓λ'␈↓α[vars;vals;alloc[vars];env]]
␈↓ ↓H␈↓αmkenv␈↓λ'␈↓α <= λ[[vars;vals;block;env]␈↓ ¬λ[null[vars] → link[block;env];
␈↓ ↓H␈↓α␈↓ ¬λ ␈↓
t␈↓α → mkenv␈↓λ'␈↓α[␈↓ ε(rest[vars];
␈↓ ↓H␈↓α␈↓ ¬λ␈↓ ε(rest[vals];
␈↓ ↓H␈↓α␈↓ ¬λ␈↓ ε(send[first[vars];first[vals];block];
␈↓ ↓H␈↓α␈↓ ¬λ␈↓ ε(env] ]]]
␈↓ ↓H␈↓␈↓↓110 Evaluation␈↓ 53.6␈↓
␈↓ ↓H␈↓Our current implementation of ␈↓αpairlis␈↓ is equivalent to:
␈↓ ↓H␈↓␈↓ ¬P␈↓αalloc <=λ[[x] ( )] ␈↓π 68␈↓α
␈↓ ↓H␈↓α␈↓ βzsend <= λ[[var;val;block] concat[mkent[var;val];block]]
␈↓ ↓H␈↓α␈↓ ∧Qlink <= λ[[block;env] append[block;env]]
␈↓ ↓H␈↓The␈αcomputational␈αbehavior␈αof␈α␈↓αpairlis␈↓␈αis␈αslightly␈αdifferent:␈αthe␈αname␈αvalue␈αpairs␈αare␈αadded␈αto␈αthe
␈↓ ↓H␈↓environment␈α⊃in␈α∩a␈α⊃different␈α∩order.␈α⊃Since␈α⊃the␈α∩variables␈α⊃in␈α∩the␈α⊃λ-list␈α⊃must␈α∩be␈α⊃distinct␈α∩from␈α⊃one
␈↓ ↓H␈↓another, this alternative environment is equivalent to the previous one.
␈↓ ↓H␈↓Symbol table manipulation is very important, so let's look at it again in a slightly different manner.
␈↓ ↓H␈↓In␈αthis␈αexample,␈αexpressions␈αand␈αtable␈αentries␈αwill␈αbe␈αwritten␈αmore␈αinformally.␈αSince␈α
the␈αevaluator
␈↓ ↓H␈↓is␈αoperating␈α
on␈αthe␈αlist␈α
representation␈αof␈αexpressions␈α
we␈αshould␈αcontinue␈α
to␈αpresent␈αthese␈α
arguments
␈↓ ↓H␈↓to␈α∀␈↓αeval␈↓␈α∀as␈α∀lists.␈α∀ However,␈α∀the␈α∀object␈α∀being␈α∀represented␈α∀might␈α∀be␈α∀more␈α∀understandable␈α∪and
␈↓ ↓H␈↓readable␈↓π 69␈↓␈α∞than␈α
the␈α∞representation␈α∞of␈α
that␈α∞object.␈α
Thus,␈α∞initially,␈α∞we␈α
will␈α∞write␈α∞␈↓αquote[␈↓λx␈↓α]␈↓␈↓π 70␈↓␈α
rather
␈↓ ↓H␈↓than␈αthe␈α
explicit␈α␈↓
R␈↓-image␈αof␈α
␈↓λx␈↓;␈αfor␈αexample,␈α
write␈α␈↓αquote[fact[3]]␈↓␈αrather␈α
than␈α␈↓α(FACT 3)␈↓.␈α
Later␈αwe
␈↓ ↓H␈↓will␈α∞simply␈α∞write␈α∞␈↓λx␈↓,␈α∞without␈α∞the␈α∞␈↓αquote␈↓␈α∞where␈α∞no␈α∞confusion␈α∞is␈α∞likely.␈α∞ With␈α∞similar␈α∞motivation,␈α∞we
␈↓ ↓H␈↓represent the symbol table between vertical bars, "|", in such a way that if a table, t␈↓β1␈↓, is:
␈↓ ↓H␈↓␈↓ αX| b␈↓βn␈↓␈↓ βH|
␈↓ ↓H␈↓␈↓ αX| ...␈↓ βH| then ␈↓αconcat␈↓ing a new element, b␈↓βn+1␈↓ onto t␈↓β1␈↓ gives:
␈↓ ↓H␈↓␈↓ αX| b␈↓β1␈↓␈↓ βH|
␈↓ ↓H␈↓␈↓ αX| b␈↓βn+1␈↓␈↓ βH|
␈↓ ↓H␈↓␈↓ αX| b␈↓βn␈↓␈↓ βH|
␈↓ ↓H␈↓␈↓ αX| ...␈↓ βH|
␈↓ ↓H␈↓␈↓ αX| b␈↓β1␈↓␈↓ βH|
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓α␈↓π 68␈↓α␈α
alloc␈↓␈αis␈α
defined␈αas␈α
a␈α
unary␈αfunction␈α
even␈αthough␈α
its␈α
argument␈αis␈α
ignored␈αhere.␈α
This␈αgenerality␈α
is
␈↓ ↓H␈↓in anticipation of future binding implementations.
␈↓ ↓H␈↓␈↓π 69␈↓␈α⊃Readability␈α⊂of␈α⊃LISP␈α⊂expressions␈α⊃is␈α⊂a␈α⊃subject␈α⊂of␈α⊃heated␈α⊂debate.␈α⊃We␈α⊂program␈α⊃using␈α⊃the␈α⊂list
␈↓ ↓H␈↓representation␈α∩and␈α∩there␈α⊃is␈α∩a␈α∩initial␈α∩period␈α⊃in␈α∩which␈α∩the␈α⊃representation␈α∩is␈α∩"difficult␈α∩to␈α⊃read".
␈↓ ↓H␈↓However␈α∂that␈α∂phemononon␈α∂is␈α∞short␈α∂lived;␈α∂the␈α∂regularity␈α∞of␈α∂LISP␈α∂expressions,␈α∂the␈α∂minimality␈α∞of
␈↓ ↓H␈↓syntax,␈α∀formatting␈α∀programs␈α∀called␈α∀"pretty␈α∀printers",␈α∀and␈α∀several␈α∀abbreviational␈α∀devices␈α∪soon
␈↓ ↓H␈↓overcome␈α
any␈α∞initial␈α
disadvantages.␈α
We␈α∞tend␈α
to␈α
represent␈α∞LISP␈α
expressions␈α
in␈α∞the␈α
meta-language
␈↓ ↓H␈↓since␈α
we␈α
wish␈α
to␈α
stress␈α
the␈α
notions␈α
of␈α
representation␈α
independence,␈α
rather␈α
than␈α
LISP's␈α
programming
␈↓ ↓H␈↓behavior.
␈↓ ↓H␈↓␈↓π 70␈↓ See page 95 for ␈↓αquote␈↓.
␈↓ ↓H␈↓␈↓↓3.6␈↓ ∩Examples of ␈↓αeval␈↓↓ 111␈↓α
␈↓ ↓H␈↓The␈α
elements␈αof␈α
the␈α
table␈αshould␈α
also␈α
be␈αpresented␈α
as␈α
␈↓
R␈↓-images,␈αbut␈α
we␈α
will␈αrepresent␈α
the␈αentries␈α
in
␈↓ ↓H␈↓a more transparent form. For example:
␈↓ ↓H␈↓αeval[quote[fact[3]]; | fact : λ[[x][x=0 → 1;␈↓
t␈↓α → *[x;fact[x-1]]]] | ]
␈↓ ↓H␈↓α␈↓ αX= eval[quote[[x=0 → 1; ␈↓
t␈↓α → *[x;fact[x-1]]]];␈↓ λ8|x : 3␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8|fact : λ[ ... ]␈↓ x| ]
␈↓ ↓H␈↓α␈↓ αX= *[3;eval[quote[[x=0 → ...];␈↓ λ8| x : 2␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| x : 3␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8|fact : λ[ ... ]␈↓ x| ]
␈↓ ↓H␈↓α␈↓ αX= *[3; *[2;eval[quote[[x=0 → ...];␈↓ λ8| x : 1␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| x : 2␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| x : 3␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8|fact : λ[ ... ]␈↓ x| ]
␈↓ ↓H␈↓α␈↓ αX= *[3; *[2; *[1;eval[quote[[x=0 → ...];␈↓ λ8| x : 0␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| x : 1␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| x : 2␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| x : 3␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8|fact : λ[ ... ]␈↓ x| ]
␈↓ ↓H␈↓α␈↓ αX= *[3; *[2; *[1;1]]] ␈↓with:␈↓α␈↓ λ8| x : 1␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| x : 2␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| ...␈↓ x|
␈↓ ↓H␈↓α␈↓ αX= *[3; *[2;1]] ␈↓with:␈↓α␈↓ λ8| x : 2␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| ...␈↓ x|
␈↓ ↓H␈↓α␈↓ αX= *[3;2] ␈↓with:␈↓α␈↓ λ8| x : 3␈↓ x|
␈↓ ↓H␈↓α␈↓ αX␈↓ λ8| ...␈↓ x|
␈↓ ↓H␈↓α␈↓ αX= 6. ␈↓with:␈↓α␈↓ λ8|fact : λ[ ... ]␈↓ x|.
␈↓ ↓H␈↓α= 6
␈↓ ↓H␈↓Notice␈αthat␈αafter␈αwe␈αwent␈αto␈αall␈αthe␈αtrouble␈αto␈αsave␈αthe␈αold␈αvalues␈αof␈α␈↓αx␈↓␈αwe␈αnever␈αhad␈αto␈αuse␈αthem.
␈↓ ↓H␈↓However,␈α
in␈αthe␈α
general␈α
case␈αof␈α
recursive␈α
evaluation␈αwe␈α
must␈α
be␈αable␈α
to␈α
save␈αand␈α
restore␈α
the␈αold
␈↓ ↓H␈↓values of variables. For example, if we had defined ␈↓αfact␈↓ as:
␈↓ ↓H␈↓α␈↓ ∧B fact <= λ[[x][x=0 → 1; ␈↓
t␈↓α → *[fact[x-1];x]]],
␈↓ ↓H␈↓then we ␈↓↓would␈↓ have to access the old binding of ␈↓αx␈↓.
␈↓ ↓H␈↓␈↓↓112 Evaluation␈↓ 53.6␈↓
␈↓ ↓H␈↓For further example, recall the definition of ␈↓αequal:
␈↓ ↓H␈↓αequal <= λ[[x;y]␈↓ β_[atom[x] → [atom[y] → eq[x;y]; ␈↓
t␈↓α → ␈↓
f␈↓α];
␈↓ ↓H␈↓α␈↓ β_ atom[y] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ β_ equal[car[x];car[y]] → equal[cdr[x];cdr[y]];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → ␈↓
f␈↓α]]
␈↓ ↓H␈↓α␈↓If we were evaluating:␈↓α
␈↓ ↓H␈↓α␈↓ ¬equal[((A . B) . C);((A . B) . D)],
␈↓ ↓H␈↓then, reading across the page, our symbol table structure would change as follows:
␈↓ ↓H␈↓α␈↓ αX|equal : λ[[x;y] ...]␈↓ ∧x| ==>␈↓ ε8|x : ((A . B) . C)␈↓ λX| ==>
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧x␈↓ ε8|y : ((A . B) . D)␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧x␈↓ ε8|equal : λ[[x;y] ... ]␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| x : (A . B)␈↓ ∧x|␈↓ ε8| x : A␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| y : (A . B)␈↓ ∧x|␈↓ ε8| y : A␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| x : ((A . B) . C)␈↓ ∧x| ==>␈↓ ε8| x : (A . B)␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| y : ((A . B) . D)␈↓ ∧x|␈↓ ε8| y : (A . B)␈↓ λX| ==>
␈↓ ↓H␈↓α␈↓ αX|equal : λ[[x;y] ... ]␈↓ ∧x|␈↓ ε8| x : ((A . B) . C)␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧x␈↓ ε8| y : ((A . B) . D)␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧x␈↓ ε8|equal : λ[[x;y] ... ]␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| x : B␈↓ ∧x|␈↓ ε8| x : C␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| y : B␈↓ ∧x|␈↓ ε8| y : D␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| x : (A . B)␈↓ ∧x|␈↓ ε8| x : ((A . B) . C)␈↓ λX| ==>
␈↓ ↓H␈↓α␈↓ αX| y : (A . B)␈↓ ∧x| ==>␈↓ ε8| y : ((A . B) . D)␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| x : ((A . B) . C)␈↓ ∧x|␈↓ ε8|equal : λ[[x;y] ... ]␈↓ λX|
␈↓ ↓H␈↓α␈↓ αX| y : ((A . B). D)␈↓ ∧x|
␈↓ ↓H␈↓α␈↓ αX|equal : λ[[x;y] ... ]␈↓ ∧x|
␈↓ ↓H␈↓α␈↓ ¬T|equal : λ[[x;y] ... ] |
␈↓ ↓H␈↓This␈α
complexity␈α
is␈α
necessary,␈αfor␈α
while␈α
we␈α
are␈α
evaluating␈α␈↓αequal[car[x];car[y]]␈↓,␈α
we␈α
rebind␈α
␈↓αx␈↓␈α
and␈α␈↓αy␈↓␈α
but
␈↓ ↓H␈↓we must save the old values of ␈↓αx␈↓ and ␈↓αy␈↓ for the possible evaluation of ␈↓αequal[cdr[x];cdr[y]].␈↓
␈↓ ↓H␈↓Before␈αmoving␈αon␈αwe␈αshould␈αexamine␈α␈↓αeval␈↓␈αand␈α␈↓αapply␈↓␈αto␈αsee␈αhow␈αthey␈αcompare␈αwith␈αour␈αprevious
␈↓ ↓H␈↓discussions␈α
of␈α
LISP␈α
evaluation.␈α
The␈α
spirit␈α
of␈α
call-by-value␈α
and␈α
conditional␈α
expression␈α
evaluation␈α
is
␈↓ ↓H␈↓maintained.␈α
λ-binding␈α
seems␈α
correct,␈α
though␈α
our␈αcurrent␈α
discussion␈α
is␈α
not␈α
complete.␈α
At␈α
least␈αone
␈↓ ↓H␈↓preconception␈αis␈αnot␈αmaintained␈αhere.␈αRecall␈αthe␈αdiscussion␈αon␈αpage 18.␈αWe␈αwanted␈αn-ary␈αfunctions
␈↓ ↓H␈↓called␈αwith␈αexactly␈αn␈α
arguments.␈αAn␈αexamination␈αof␈α
the␈αstructure␈αof␈α␈↓αeval␈↓␈α
and␈α␈↓αapply␈↓␈αshows␈αthat␈αif␈α
a
␈↓ ↓H␈↓function␈α∞expecting␈α
␈↓↓n␈↓␈α∞arguments␈α
is␈α∞presented␈α
with␈α∞fewer,␈α
then␈α∞the␈α
result␈α∞is␈α
undefined;␈α∞but␈α
if␈α∞it␈α
is
␈↓ ↓H␈↓given ␈↓↓more␈↓ arguments than necessary then the calculation is performed. For example:
␈↓ ↓H␈↓␈↓↓3.6␈↓ ∩Examples of ␈↓αeval␈↓↓ 113␈↓α
␈↓ ↓H␈↓αeval[(CONS (QUOTE A) (QUOTE B) (QUOTE C));NIL]
␈↓ ↓H␈↓α␈↓ ¬H= eval[(CONS (QUOTE A) (QUOTE B));NIL]
␈↓ ↓H␈↓α␈↓ ¬H= (A . B)
␈↓ ↓H␈↓This␈α∞shows␈α∂one␈α∞of␈α∂the␈α∞pitfalls␈α∂in␈α∞defining␈α∂a␈α∞language␈α∂by␈α∞an␈α∂evaluator.␈α∞ If␈α∂the␈α∞intuitions␈α∂of␈α∞the
␈↓ ↓H␈↓language␈αspecifiers␈α
are␈αfaulty␈α
or␈αincomplete␈α
then␈αeither␈αwe␈α
are␈αfaced␈α
with␈αmaintaining␈α
that␈αfaulty
␈↓ ↓H␈↓judgement, or we must lobby for a "revised report"␈↓π 71␈↓.
␈↓ ↓H␈↓The␈αdefinition␈α
of␈αa␈α
language␈αby␈α
an␈αevaluator␈αwritten␈α
in␈αthat␈α
language␈αis␈α
subject␈αto␈αother␈α
criticisms.
␈↓ ↓H␈↓The␈αtroublesome␈αareas␈αof␈αour␈αdescription␈αof␈αLISP's␈αevaluation␈αincluded␈αλ-binding,␈αcalling␈αstyles␈αin
␈↓ ↓H␈↓general␈α⊃and␈α⊂call-by-value␈α⊃in␈α⊂particular,␈α⊃and␈α⊂left-to-right␈α⊃order␈α⊂of␈α⊃evaluation.␈α⊂We␈α⊃wrote␈α⊃␈↓αeval␈↓␈α⊂to
␈↓ ↓H␈↓explicate␈αthe␈αmeaning␈αof␈αthese␈αconstructs,␈αyet␈α
within␈α␈↓αeval␈↓␈αwe␈αoften␈αrelied␈αon␈αexactly␈αthese␈α
constructs
␈↓ ↓H␈↓to␈α
convey␈α
our␈α
intent.␈α
Now,␈α
our␈α
description␈α
in␈α
not␈α
entirely␈α
circular;␈α
␈↓αeval␈↓␈α
does␈α
convey␈α
much␈α∞of␈α
our
␈↓ ↓H␈↓intention␈α∞to␈α
the␈α∞reader,␈α
but␈α∞the␈α
discussion␈α∞of␈α
␈↓↓how␈↓␈α∞these␈α
constructs␈α∞operate␈α
is␈α∞either␈α
implicit␈α∞or␈α
is
␈↓ ↓H␈↓explained␈αby␈αusing␈αthe␈αsame␈αkind␈αof␈αconstructs.␈α In␈αgaining␈αa␈αclearer␈αunderstanding␈αof␈αwhat␈αLISP
␈↓ ↓H␈↓constructs␈α∞mean,␈α∞␈↓αeval␈↓␈α∞is␈α∞exemplary.␈α∞Indeed␈α∞many␈α
of␈α∞the␈α∞details␈α∞of␈α∞how␈α∞these␈α∞constructs␈α∞work␈α
are
␈↓ ↓H␈↓irrelevant␈αto␈αsuch␈αan␈αunderstanding.␈αWhen␈αwe␈αattempt␈αto␈αimplement␈αa␈αlanguage␈αfeature␈αwe␈αcannot
␈↓ ↓H␈↓assume␈αthe␈αexistence␈αof␈αthat␈αfeature;␈α
the␈αimplementation␈αmust␈αbe␈αprepared␈αfrom␈αa␈α
combination␈αof
␈↓ ↓H␈↓more␈α⊂primitive␈α∂components.␈α⊂As␈α∂we␈α⊂proceed␈α∂through␈α⊂the␈α∂text␈α⊂we␈α∂will␈α⊂introduce␈α⊂the␈α∂mechanisms
␈↓ ↓H␈↓which␈α∂are␈α∂necessary␈α∂to␈α∂implement␈α∂LISP␈α∂and,␈α∂indeed,␈α∂the␈α∂constructs␈α∂of␈α∂most␈α∂other␈α∂languages.␈α∂In
␈↓ ↓H␈↓Section 4.4␈α⊃we␈α⊂give␈α⊃several␈α⊃alternative␈α⊂algorithms␈α⊃for␈α⊃␈↓αeval␈↓.␈α⊂They␈α⊃will␈α⊃evolve␈α⊂to␈α⊃an␈α⊃␈↓αeval␈↓␈α⊂which
␈↓ ↓H␈↓makes␈α∂explicit␈α∞most␈α∂of␈α∞the␈α∂mechanisms␈α∞we␈α∂need.␈α∞In␈α∂Chapter 5␈α∞we␈α∂will␈α∞begin␈α∂to␈α∂discuss␈α∞efficient
␈↓ ↓H␈↓representations␈α⊗for␈α⊗LISP's␈α∃data␈α⊗structures,␈α⊗control␈α∃structures,␈α⊗and␈α⊗primitive␈α⊗operations.␈α∃The
␈↓ ↓H␈↓remainder of this chapter will explicate further features of LISP in preparation for that discussion.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓␈↓↓I␈↓␈α∀Which␈α∀parts␈α∀of␈α∃␈↓αeval␈↓␈α∀and␈α∀Co.␈α∀allow␈α∀correct␈α∃evaluation␈α∀of␈α∀functions␈α∀applied␈α∀to␈α∃too␈α∀many
␈↓ ↓H␈↓arguments?
␈↓ ↓H␈↓␈↓↓II␈↓␈α∩On␈α⊃page 112␈α∩we␈α⊃noted␈α∩that␈α⊃the␈α∩evaluator␈α⊃performs␈α∩"correctly"␈α⊃when␈α∩evaluating␈α∩forms␈α⊃like
␈↓ ↓H␈↓␈↓αcons[A;B;C]␈↓.␈α Can␈αyou␈αfind␈αother␈αanomalies␈αin␈α␈↓αeval␈↓␈αand␈αfriends?␈αThat␈αis,␈αplaces␈αwhere␈αunexpected
␈↓ ↓H␈↓results are obtained?
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 71␈↓␈α⊂For␈α⊂example␈α∂the␈α⊂LISP 1.6␈α⊂system␈α∂([Qua 72])␈α⊂gives␈α⊂␈↓α(A . A)␈↓␈α∂for␈α⊂␈↓αcons[A]␈↓;␈α⊂the␈α⊂MacLISP␈α∂system
␈↓ ↓H␈↓([Moo 74]) gives ␈↓α(A . ␈↓"missing-arg"␈↓α)␈↓; and InterLISP ([Int 75]) gives ␈↓α(A)␈↓.
␈↓ ↓H␈↓␈↓↓114 Evaluation␈↓ 53.7␈↓
␈↓ ↓H␈↓␈↓ ¬u␈↓↓3.7 Variables␈↓
␈↓ ↓H␈↓Let's␈αlook␈αmore␈αclosely␈αat␈αλ-binding␈αin␈α␈↓αeval␈↓.␈αThe␈αscheme␈αpresented␈αseems␈αreasonable,␈αbut␈αas␈αin␈αthe
␈↓ ↓H␈↓case ␈↓αcons[A;B;C]␈↓, there may be more expressed here than we anticipated.
␈↓ ↓H␈↓If␈αwe␈αasked␈α␈↓αeval␈↓␈α
to␈αcompute␈α␈↓αf[2]␈↓,␈αgiven␈αa␈α
representation␈αfor␈α␈↓αf <= λ[[x] x + y]␈↓␈αbut␈α
no␈αrepresenation
␈↓ ↓H␈↓for␈α⊃the␈α⊃value␈α⊃of␈α⊃␈↓αy␈↓␈α⊃it␈α⊃would␈α⊃complain.␈α⊃It␈α∩would␈α⊃find␈α⊃␈↓αf␈↓,␈α⊃bind␈α⊃␈↓α2␈↓␈α⊃to␈α⊃␈↓αx␈↓;␈α⊃and␈α⊃it␈α⊃would␈α∩begin␈α⊃the
␈↓ ↓H␈↓evaluation␈αof␈αthe␈αbody␈αof␈α␈↓αf␈↓,␈αit␈αwould␈αfind␈α␈↓αx␈↓'s␈αvalue,␈αbut␈αit␈αwould␈αfind␈αno␈αvalue␈αfor␈α␈↓αy␈↓.␈αHowever,␈αif
␈↓ ↓H␈↓we␈αasked␈αit␈α
to␈αevaluate␈αthe␈αform␈α
␈↓αλ[[y] f[2]][1]␈↓␈αit␈α␈↓↓would␈↓␈αwork.␈α
It␈αwould␈αfind␈αthe␈α
value␈αof␈α␈↓αy␈↓␈αto␈α
be␈α␈↓α1␈↓
␈↓ ↓H␈↓and would get a final answer of ␈↓α3␈↓ as expected. You should convince yourself of this assertion.
␈↓ ↓H␈↓Within␈αthe␈αevaluation␈αof␈α␈↓αf[2]␈↓␈αin␈α␈↓αλ[[y] f[2]][1]␈↓␈αthe␈αvariable␈α␈↓αy␈↓␈αhas␈αa␈αdifferent␈αcharacter␈αfrom␈αthat␈αof
␈↓ ↓H␈↓␈↓αx␈↓.␈α∞ The␈α∞value␈α∂of␈α∞␈↓αx␈↓␈α∞is␈α∂found␈α∞within␈α∞the␈α∞latest␈α∂λ-binding,␈α∞whereas␈α∞␈↓αy␈↓␈α∂was␈α∞bound␈α∞in␈α∂a␈α∞dynamically
␈↓ ↓H␈↓surrounding␈α
λ-binding.␈α
That␈α
is,␈αthe␈α
λ-expression␈α
which␈α
bound␈α
␈↓αy␈↓␈αtook␈α
effect␈α
before␈α
the␈α
binding␈αof␈α
␈↓αx␈↓
␈↓ ↓H␈↓and␈αis␈αstill␈αin␈αeffect␈αwhen␈αthe␈αbinding␈αof␈α␈↓αx␈↓␈αis␈αmade.␈αWe␈αdo␈αhave␈αaccess␈αto␈α␈↓αy␈↓'s␈αbinding␈αin␈αthis␈αcase;
␈↓ ↓H␈↓the␈α␈↓αlookup␈↓␈αroutine␈αwill␈αlocate␈α␈↓αy␈↓'s␈αvalue.␈α There␈αis␈αa␈αthird␈αkind␈αof␈αname-value␈αassociation␈αpresent␈αin
␈↓ ↓H␈↓these␈α∞examples:␈α∞we␈α∞expect␈α∞that␈α
the␈α∞symbol␈α∞"+"␈α∞is␈α∞recognized␈α
during␈α∞the␈α∞evaluation␈α∞as␈α∞denoting␈α
a
␈↓ ↓H␈↓procedure␈αfor␈αcomputing␈αthe␈αsum␈αof␈α
two␈αnumbers.␈α In␈αprevious␈αdiscussions␈αwe␈αhave␈α
assumed␈αthat
␈↓ ↓H␈↓"+"␈αwas␈αpre-defined␈αinside␈α␈↓αapply␈↓␈αand␈αtherefore␈αexplicitly␈αrecognized.␈αFinally,␈αin␈αthe␈αfirst␈αexample,␈α
a
␈↓ ↓H␈↓fourth␈α∀kind␈α∪of␈α∀variable␈α∀usage␈α∪occurred.␈α∀The␈α∀variable␈α∪␈↓αy␈↓␈α∀had␈α∀no␈α∪associated␈α∀value␈α∀when␈α∪the
␈↓ ↓H␈↓computation expected one. In this section we wish to examine properties of variables.
␈↓ ↓H␈↓The␈αimplementation␈αof␈αλ-bindings␈αdescribed␈αin␈α␈↓αpairlis␈↓␈α(page 104)␈αis␈αslightly␈αmisleading.␈αThere,␈αthe
␈↓ ↓H␈↓new␈α∞λ-bindings␈α∞are␈α∞␈↓αconcat␈↓-ed␈α∞onto␈α∞the␈α∞front␈α∞of␈α
the␈α∞existing␈α∞table.␈α∞They␈α∞go␈α∞on␈α∞in␈α∞a␈α
one-at-a-time
␈↓ ↓H␈↓fashion␈α
even␈αthough␈α
they␈α
are␈αto␈α
be␈α
thought␈αof␈α
as␈α
a␈αlogical␈α
unit:␈α
at␈αthe␈α
language␈α
level␈αthey␈α
all␈αgo␈α
on
␈↓ ↓H␈↓together,␈α⊂and␈α⊂they␈α∂all␈α⊂come␈α⊂off␈α∂together.␈α⊂It␈α⊂is␈α⊂the␈α∂structure␈α⊂of␈α⊂this␈α∂table␈α⊂which␈α⊂we␈α⊂should␈α∂also
␈↓ ↓H␈↓examine. To these ends we now introduce some terminology.
␈↓ ↓H␈↓Consider the evaluation of the expression:
␈↓ ↓H␈↓α␈↓ ∧Hλ[[y] equal[λ[[x] cons[x;y]][(A . B)];x]][A]
␈↓ ↓H␈↓in an environment where the definition of ␈↓αequal␈↓ is known.
␈↓ ↓H␈↓We␈α⊃evaluate␈α⊃the␈α⊃main␈α⊃argument␈α∩␈↓αA␈↓,␈α⊃and␈α⊃perform␈α⊃the␈α⊃λ-binding␈α∩of␈α⊃␈↓αA␈↓␈α⊃to␈α⊃␈↓αy␈↓.␈α⊃This␈α∩operation␈α⊃of
␈↓ ↓H␈↓λ-binding␈αcreates␈α
what␈αwe␈α
call␈αa␈α␈↓↓local␈α
symbol␈αtable␈↓␈α
and␈αthe␈αvariables␈α
bound␈αin␈α
that␈αlocal␈αtable␈α
are
␈↓ ↓H␈↓called␈α⊃␈↓↓local␈α∩bindings␈↓␈α⊃for␈α∩the␈α⊃body␈α⊃of␈α∩the␈α⊃λ-expression.␈α∩We␈α⊃now␈α⊃begin␈α∩the␈α⊃evaluation␈α∩of␈α⊃the
␈↓ ↓H␈↓arguments␈α
to␈α
␈↓αequal␈↓.␈α
The␈α
first␈α
argument␈αis␈α
itself␈α
an␈α
expression␈α
requiring␈α
λ-binding.␈α
We␈αevaluate␈α
it's
␈↓ ↓H␈↓argument␈α
and␈αbind␈α
␈↓α(A . B)␈↓␈αto␈α
␈↓αx␈↓.␈αThis␈α
creates␈αa␈α
local␈αbinding␈α
for␈α␈↓αx␈↓.␈α
In␈αthe␈α
process␈αof␈α
making␈α␈↓αx␈↓␈α
local
␈↓ ↓H␈↓what␈αhappens␈αto␈α
␈↓αy␈↓?␈α Notice␈αthat␈α
the␈αbinding␈αprocess␈α
has␈αnot␈αmade␈α
␈↓αy␈↓␈αinaccessible:␈αwe␈α
can␈αcompute
␈↓ ↓H␈↓␈↓αcons[x;y]␈↓␈α∞even␈α∞though␈α∂␈↓αy␈↓␈α∞is␈α∞not␈α∂local.␈α∞Variables␈α∞like␈α∞␈↓αy␈↓␈α∂which␈α∞are␈α∞accessible,␈α∂but␈α∞not␈α∞local,␈α∂we␈α∞call
␈↓ ↓H␈↓␈↓↓non-local␈↓␈α
variables.␈α
Thus␈α
both␈α
␈↓αy␈↓␈α
and␈α
␈↓αcons␈↓␈αare␈α
non-local␈α
variables␈α
in␈α
our␈α
evaluation␈α
of␈α␈↓αcons[x;y]␈↓.
␈↓ ↓H␈↓There␈α∂is␈α∂a␈α∞further␈α∂distinction␈α∂between␈α∞␈↓αy␈↓␈α∂and␈α∂␈↓αcons␈↓:␈α∞We␈α∂expect␈α∂␈↓αcons␈↓␈α∞to␈α∂be␈α∂a␈α∂predefined␈α∞function;
␈↓ ↓H␈↓indeed␈α
␈↓αcons␈↓␈αhas␈α
not␈αbeen␈α
λ-bound␈αany␈α
where␈α
in␈αour␈α
computation.␈αVariables␈α
like␈α␈↓αcons␈↓␈α
we␈α
will␈αcall
␈↓ ↓H␈↓␈↓↓global variables␈↓.
␈↓ ↓H␈↓␈↓↓3.7␈↓ {Variables 115␈↓
␈↓ ↓H␈↓Global␈α
variables␈α
include␈α
predefined␈α
function␈αnames,␈α
␈↓αcar␈↓,␈α
␈↓αcdr␈↓,␈α
etc,␈α
and␈αvariables␈α
like␈α
␈↓αt␈↓␈α
and␈α
␈↓αnil␈↓.␈α A
␈↓ ↓H␈↓useful␈α∂interpretation␈α∂of␈α∂global␈α∂variables␈α∂is␈α∂that␈α∂they␈α∂are␈α∂bound␈α∂in␈α∂the␈α∂initial␈α∂symbol␈α⊂table,␈α∂also
␈↓ ↓H␈↓called␈α
the␈α␈↓↓global␈α
table␈↓␈↓π 72␈↓.␈α Non-local␈α
variables␈αwhich␈α
are␈αλ-bound␈α
somewhere␈αin␈α
the␈α
symbol␈αtable
␈↓ ↓H␈↓we␈α
call␈α
␈↓↓free␈α
variables␈↓,␈α∞and␈α
variables␈α
which␈α
have␈α
␈↓↓some␈↓␈α∞accessible␈α
binding␈α
at␈α
the␈α
current␈α∞point␈α
in
␈↓ ↓H␈↓the computation are called ␈↓↓bound variables␈↓␈↓π 73␈↓.
␈↓ ↓H␈↓Finally␈α∃the␈α∃first␈α∃argument␈α∃to␈α∃␈↓αequal␈↓␈α∃is␈α∃evaluated␈α∃giving␈α∃␈↓α((A . B) . A)␈↓.␈α∃ As␈α∃we␈α⊗complete␈α∃that
␈↓ ↓H␈↓evaluation␈αthe␈αlocal␈αbinding␈αfor␈α␈↓αx␈↓␈αis␈αremoved,␈αand␈α␈↓αy␈↓␈αbecomes␈αlocal␈αagain.␈αWe␈αexamine␈α
the␈αsecond
␈↓ ↓H␈↓argument␈αto␈α
␈↓αequal␈↓,␈αwhich␈αis␈α
␈↓αx␈↓,␈αand␈αnow␈α
find␈αthere␈αis␈α
no␈αbinding␈αfor␈α
that␈αvariable.␈αVariables␈α
which
␈↓ ↓H␈↓have␈α
no␈α∞binding␈α
of␈α∞any␈α
kind␈α∞at␈α
the␈α∞time␈α
we␈α
ask␈α∞for␈α
a␈α∞value␈α
are␈α∞called␈α
␈↓↓unbound␈α∞variables␈↓.␈α
The
␈↓ ↓H␈↓local, free, and global variables make up the class of ␈↓↓bound variables␈↓.
␈↓ ↓H␈↓For␈α∂a␈α⊂computation␈α∂to␈α⊂be␈α∂meaningful,␈α⊂each␈α∂variable␈α⊂which␈α∂that␈α⊂computation␈α∂references␈α⊂must␈α∂be
␈↓ ↓H␈↓bound␈α∞␈↓↓somewhere␈↓␈α
when␈α∞we␈α
ask␈α∞for␈α
its␈α∞value.␈α
So␈α∞the␈α
computation␈α∞of␈α
our␈α∞current␈α∞example␈α
would
␈↓ ↓H␈↓fail.␈α
Since␈αwe␈α
are␈α
doing␈αcall-by-value,␈α
it␈α
would␈αfail␈α
even␈α
before␈αwe␈α
asked␈α
for␈αthe␈α
definition␈αof␈α
␈↓αequal␈↓.
␈↓ ↓H␈↓One of our tasks will be to discuss where definitions such as that for ␈↓αequal␈↓ should be kept.
␈↓ ↓H␈↓Here is a diagram of our characterization of variables:
␈↓"␈↓ ↓H␈↓∂ ␈↓variables␈↓∂
␈↓"␈↓ ↓H␈↓∂ ~
␈↓"␈↓ ↓H␈↓∂ ⊂ααααααα∀ααααααα⊃
␈↓"␈↓ ↓H␈↓∂ ~ ~
␈↓"␈↓ ↓H␈↓∂ ␈↓non-local␈↓∂ ␈↓local␈↓∂
␈↓"␈↓ ↓H␈↓∂ ~
␈↓"␈↓ ↓H␈↓∂ ⊂αα∀ααααααπααααααααααα⊃
␈↓"␈↓ ↓H␈↓∂ ~ ~ ~
␈↓"␈↓ ↓H␈↓∂ ␈↓free␈↓∂ ␈↓global␈↓∂ ␈↓unbound␈↓∂
␈↓ ↓H␈↓Notice␈α⊃that␈α⊃a␈α⊃variable␈α⊃which␈α⊃is␈α⊃initially␈α∩global␈α⊃may␈α⊃become␈α⊃local␈α⊃and␈α⊃then␈α⊃free␈α⊃by␈α∩virtue␈α⊃of
␈↓ ↓H␈↓λ-bindings.
␈↓ ↓H␈↓The␈α∂binding␈α∞strategy␈α∂for␈α∞local␈α∂variables␈α∂is␈α∞reasonably␈α∂uniform␈α∞in␈α∂programming␈α∂languages:␈α∞bind
␈↓ ↓H␈↓some␈α⊂form␈α⊂of␈α⊂the␈α⊂actual␈α⊂parameters␈↓π 74␈↓␈α⊂to␈α⊂the␈α⊂formal␈α⊂parameters␈α⊂and␈α⊂evaluate␈α⊂the␈α⊂body␈α⊂of␈α∂the
␈↓ ↓H␈↓definition.␈α
One␈α
of␈α∞the␈α
difficulties␈α
in␈α∞programming␈α
languages␈α
is␈α∞deciding␈α
what␈α
value␈α∞to␈α
associate
␈↓ ↓H␈↓with␈α⊃a␈α⊃non-local␈α⊂variable.␈α⊃ In␈α⊃LISP,␈α⊃it␈α⊂is␈α⊃clear␈α⊃␈↓↓how␈↓␈α⊃values␈α⊂get␈α⊃associated;␈α⊃it␈α⊃happens␈α⊂through
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 72␈↓␈α
This␈α
analogy␈α
breaks␈α
down␈α
somewhat␈α
in␈α
that␈α
usual␈α
implementations␈α
of␈α
LISP␈α
allow␈α
this␈αglobal
␈↓ ↓H␈↓table␈α⊂to␈α⊂be␈α∂augmented;␈α⊂for␈α⊂example,␈α∂by␈α⊂function␈α⊂definitions␈α∂using␈α⊂a␈α⊂version␈α∂of␈α⊂"<=".␈α⊂Thus␈α∂the
␈↓ ↓H␈↓global table can be enlarged whereas a true λ-binding involves a fixed number of variables.
␈↓ ↓H␈↓␈↓π 73␈↓␈α
Our␈αnotion␈α
of␈α
free␈αand␈α
bound␈αvariables␈α
has␈α
a␈αdecidedly␈α
computational␈α
flavor,␈αin␈α
contrast␈αto␈α
the
␈↓ ↓H␈↓mathematical definitions of "free" and "bound" given on page 155.
␈↓ ↓H␈↓␈↓π 74␈↓ evaluated or unevaluated
␈↓ ↓H␈↓␈↓↓116 Evaluation␈↓ 53.7␈↓
␈↓ ↓H␈↓λ-binding␈α
or␈α
by␈α
virtue␈α
of␈α
an␈α
initial␈α
entry␈α
in␈α
the␈α
symbol␈α
table.␈α
The␈α
scheme␈α
which␈α
LISP␈α∞uses␈α
for
␈↓ ↓H␈↓discovering␈αthe␈αvalue␈αof␈αany␈αvariable␈αis␈αto␈αproceed␈αlinearly␈αdown␈αthe␈αsymbol␈αtable,␈αlooking␈αfor␈αthe
␈↓ ↓H␈↓␈↓↓latest␈↓␈αbinding.␈α This␈αscheme␈αis␈αcalled␈α␈↓↓dynamic␈αbinding␈↓.␈αIt␈α␈↓↓usually␈↓␈αresults␈αin␈αuncovering␈αthe␈αvalue
␈↓ ↓H␈↓that␈αis␈αexpected;␈αbut␈αnot␈αalways␈αas␈αwe␈αwill␈αsee␈αin␈αSection 3.10.␈α Conceptually,␈αthe␈αdynamic␈αbinding
␈↓ ↓H␈↓scheme␈α∞corresponds␈α∞to␈α∂the␈α∞physical␈α∞replacement␈α∂of␈α∞the␈α∞function␈α∞call␈α∂with␈α∞the␈α∞function␈α∂body␈α∞and
␈↓ ↓H␈↓then␈α⊃an␈α⊃evaluation␈α∩of␈α⊃the␈α⊃resulting␈α⊃expression.␈α∩Free␈α⊃variables␈α⊃whose␈α⊃bindings␈α∩are␈α⊃determined
␈↓ ↓H␈↓dynamically are called ␈↓↓fluid variables␈↓.
␈↓ ↓H␈↓In␈α
review,␈αthe␈α
evaluation␈αof␈α
a␈α
typical␈αfunction-call␈α
will␈αinvolve␈α
the␈α
evaluation␈αof␈α
the␈αarguments,␈α
the
␈↓ ↓H␈↓binding␈α
of␈αthe␈α
λ-variables␈α
to␈αthose␈α
values,␈α
the␈αaddition␈α
of␈α
these␈αnew␈α
bindings␈α
to␈αthe␈α
front␈α
of␈αthe
␈↓ ↓H␈↓symbol␈αtable,␈αand␈αfinally␈αthe␈αevaluation␈αof␈αthe␈αbody␈αof␈αthe␈αfunction.␈α That␈αsegment␈αof␈α
the␈αsymbol
␈↓ ↓H␈↓table␈α∞which␈α∞we␈α∞have␈α∞just␈α∞added␈α∞by␈α∞the␈α∞λ-binding␈α∞will␈α∞be␈α∞called␈α∞the␈α∞␈↓↓local␈α∞symbol␈α∞table␈↓␈α∞or␈α
local
␈↓ ↓H␈↓environment.␈αThe␈αvariables␈αwhich␈αappear␈αin␈αthat␈αsegment␈αare␈αthe␈αlocal␈αvariables.␈α The␈αremainder
␈↓ ↓H␈↓of␈αthe␈αsymbol␈αtable␈αmakes␈αup␈αthe␈α␈↓↓non-local␈αtable␈↓.␈α Variables␈αwhich␈αappear␈αin␈αthe␈αglobal␈αtable␈αbut
␈↓ ↓H␈↓not␈α
in␈αany␈α
local␈αtable␈α
are␈αthe␈α
␈↓↓global␈αvariables␈↓.␈α
Free␈αvariables␈α
are␈αbound␈α
somewhere␈α
between␈αthe
␈↓ ↓H␈↓local␈α
table␈α∞and␈α
the␈α∞global␈α
table.␈α
Variables␈α∞which␈α
are␈α∞local␈α
to␈α
a␈α∞form-evaluation␈α
are␈α∞those␈α
which
␈↓ ↓H␈↓were␈αpresent␈αin␈αthe␈αλ-binding.␈α We␈αfirst␈αwish␈αto␈αdevelop␈αa␈αuseful␈αnotation␈αfor␈αdescribing␈αbindings
␈↓ ↓H␈↓before␈αdelving␈α
further␈αinto␈α
the␈αintricacies␈α
of␈αbinding␈α
strategies.␈α That␈α
discussion␈αwill␈α
be␈αthe␈α
content
␈↓ ↓H␈↓of Section 3.11.
␈↓ ↓H␈↓↓␈↓ ε⊃Problems
␈↓ ↓H␈↓I␈α⊂Write␈α⊂a␈α∂LISP␈α⊂predicate,␈α⊂␈↓αnon␈α∂<=␈α⊂λ[[x;e]␈α⊂...␈α∂]␈↓,␈α⊂which␈α⊂will␈α∂give␈α⊂␈↓
t␈↓␈α⊂just␈α∂in␈α⊂the␈α⊂case␈α∂that␈α⊂␈↓αx␈↓␈α⊂and␈α∂␈↓αe␈↓
␈↓ ↓H␈↓represent a variable and a λ-expression respectively, and ␈↓αx␈↓ is non-local to ␈↓αe␈↓.
␈↓ ↓H␈↓␈↓ ∧w␈↓↓3.8 Environments and Bindings␈↓
␈↓ ↓H␈↓This␈α
section␈α
will␈α
introduce␈α
one␈α
more␈αnotation␈α
for␈α
describing␈α
symbol␈α
tables␈α
or␈α
environments.␈αThis
␈↓ ↓H␈↓notation,␈α∞due␈α
to␈α∞J.␈α∞Weizenbaum ([Wei 68]),␈α
only␈α∞shows␈α
the␈α∞abstract␈α∞structure␈α
of␈α∞the␈α∞symbol␈α
table
␈↓ ↓H␈↓manipulations␈αduring␈α
evaluation.␈αIts␈αsimplicity␈α
will␈αbe␈αof␈α
great␈αbenefit␈αwhen␈α
we␈αintroduce␈αthe␈α
more
␈↓ ↓H␈↓complex binding schemes necessary for function-valued functions in Section 3.10.
␈↓ ↓H␈↓In␈α
the␈αprevious␈α
discussions␈αit␈α
has␈αbeen␈α
sufficient␈αto␈α
simply␈α
think␈αof␈α
a␈αsymbol␈α
table␈αas␈α
a␈αsequence␈α
of
␈↓ ↓H␈↓pairs;␈αeach␈α
pair␈αwas␈α
a␈αvariable␈α
and␈αits␈αassociated␈α
value.␈αThis␈α
sufficed␈αbecause␈α
we␈αdealt␈α
only␈αwith
␈↓ ↓H␈↓λ-variables;␈αwe␈αignored␈αthe␈αpossibility␈αof␈αfree␈αvariables.␈αAs␈αlong␈αas␈αwe␈αadded␈αthe␈αλ-bindings␈αto␈αthe
␈↓ ↓H␈↓␈↓↓front␈↓␈α∂of␈α∂the␈α∂sequence␈α∂representing␈α∂the␈α∂symbol␈α∂table␈α∂we␈α∂showed␈α∂that␈α∂expected␈α∂evaluation␈α∞would
␈↓ ↓H␈↓result.␈α
Local␈α
values␈α
were␈α
found␈α
in␈α
the␈α
table;␈α
global␈α
values␈α
were␈α
found␈α
by␈α
explicit␈α
recognizers␈αin␈α
␈↓αeval␈↓
␈↓ ↓H␈↓and␈α∩␈↓αapply␈↓.␈α∩ With␈α⊃the␈α∩advent␈α∩of␈α∩free␈α⊃variables,␈α∩however,␈α∩it␈α∩will␈α⊃be␈α∩necessary␈α∩to␈α∩examine␈α⊃the
␈↓ ↓H␈↓structure␈α⊂of␈α∂environments␈α⊂more␈α∂closely.␈α⊂ We␈α∂will␈α⊂describe␈α∂our␈α⊂environments␈α∂in␈α⊂terms␈α∂of␈α⊂a␈α∂local
␈↓ ↓H␈↓symbol table augmented by a description of where to look for the non-local values.
␈↓ ↓H␈↓Instead␈αof␈αhaving␈α
one␈αamorphous␈αsequential␈α
symbol␈αtable,␈αwe␈α
envision␈αa␈αsequence␈α
of␈αtables.␈αOne␈α
is
␈↓ ↓H␈↓␈↓↓3.8␈↓ λEnvironments and Bindings 117␈↓
␈↓ ↓H␈↓the␈α
local␈αtable,␈α
and␈α
its␈αsuccessor␈α
in␈αthe␈α
sequence␈α
is␈αthe␈α
previous␈α
local␈αtable.␈α
The␈αinformation␈α
telling
␈↓ ↓H␈↓where␈α∂to␈α⊂find␈α∂the␈α⊂previous␈α∂table␈α∂is␈α⊂called␈α∂the␈α⊂␈↓↓access␈α∂chain␈↓␈α∂or␈α⊂␈↓↓access␈α∂link␈↓.␈α⊂ Thus␈α∂if␈α⊂tables␈α∂are
␈↓ ↓H␈↓represented by E␈↓βi␈↓ and the access link by ␈↓→␈↓ then we might represent a symbol table as:
␈↓ ↓H␈↓␈↓ ¬_␈↓α(␈↓E␈↓βn␈↓ → ␈↓E␈↓βn-1␈↓ → ␈↓ ...␈↓→ ␈↓E␈↓β1 ␈↓→␈↓ E␈↓β0␈↓α)
␈↓ ↓H␈↓where E␈↓βn␈↓ is the local or current segment of the table. We reserve E␈↓β0␈↓ to name the global table.
␈↓ ↓H␈↓LISP␈αfinds␈αlocal␈αbindings␈αin␈αthe␈αlocal␈αtable␈αand␈αuses␈αthe␈αaccess␈αchain␈αto␈αfind␈αbindings␈αof␈αnon-local
␈↓ ↓H␈↓variables. If a variable is not found in any of the tables, then it is unbound.
␈↓ ↓H␈↓An environment will be described as:
␈↓ ↓H␈↓␈↓ ¬x␈↓ ε8␈↓ Form␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓ ε8E␈↓βlocal␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓ ε8| E␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬x_________
␈↓ ↓H␈↓␈↓ ¬xvar␈↓ ε8| value
␈↓ ↓H␈↓␈↓ ¬x␈↓αv␈↓β1␈↓␈↓ ε8| ␈↓ val␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓αv␈↓β2␈↓␈↓ ε8| ␈↓ val␈↓β2␈↓
␈↓ ↓H␈↓␈↓ ¬x .....
␈↓ ↓H␈↓␈↓ ¬x␈↓αv␈↓βn␈↓␈↓ ε8| ␈↓ val␈↓βn␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓ ε8|
␈↓ ↓H␈↓␈↓ Form␈↓␈α⊂is␈α⊂the␈α⊂current␈α⊂form␈α⊂being␈α⊂evaluated.␈α⊂ E␈↓βlocal␈↓␈α⊂is␈α⊂the␈α⊂name␈α⊂of␈α⊂the␈α⊂current␈α⊃environment␈α⊂or
␈↓ ↓H␈↓symbol␈α
table.␈α
Let␈α
␈↓αx␈↓␈α
be␈α
a␈α
variable␈α
appearing␈α
in␈α␈↓ Form␈↓.␈α
If␈α
␈↓αx␈↓␈α
is␈α
not␈α
found␈α
among␈α
the␈α
␈↓αv␈↓βj␈↓'s,␈αthen␈α
entries
␈↓ ↓H␈↓in␈α∂the␈α∂table␈α∂named␈α⊂E␈↓βi␈↓␈α∂are␈α∂examined.␈α∂ If␈α⊂the␈α∂variable␈α∂is␈α∂not␈α⊂found␈α∂in␈α∂E␈↓βi␈↓␈α∂then␈α⊂the␈α∂environment
␈↓ ↓H␈↓mentioned␈α∞in␈α∞the␈α∞upper␈α∞right-hand␈α∞quadrant␈α∞of␈α∂E␈↓βi␈↓␈α∞is␈α∞searched.␈α∞The␈α∞search␈α∞will␈α∞terminate␈α∂if␈α∞the
␈↓ ↓H␈↓variable␈α∞is␈α∞found;␈α∞the␈α∞value␈α∞is␈α∞then␈α∞the␈α∞corresponding␈α∞␈↓ val␈↓βj␈↓.␈α∞ If␈α∞␈↓αx␈↓␈α∞is␈α∞not␈α∞found␈α∞locally,␈α∞and␈α
the
␈↓ ↓H␈↓symbol "/" appears in the right-hand quadrant, then ␈↓αx␈↓ is unbound.
␈↓ ↓H␈↓The␈αnotation␈αis␈αused␈αas␈αfollows:␈αwhen␈αwe␈αbegin␈αthe␈αevaluation␈αof␈αa␈αform,␈αthe␈αinitial␈αtable␈αE␈↓β0␈↓␈αis␈αset
␈↓ ↓H␈↓up␈α
with␈α
"/"␈αin␈α
its␈α
access␈αfield.␈α
The␈α
execution␈αof␈α
a␈α
function␈αdefinition,␈α
say␈α
␈↓αf <= λ[[x;y] x␈↓π2␈↓α + y]␈↓,␈αwill
␈↓ ↓H␈↓add␈α∞an␈α∂appropriate␈α∞entry␈α∂to␈α∞the␈α∂table,␈α∞binding␈α∂␈↓αf␈↓␈α∞to␈α∂its␈α∞lambda␈α∂definition␈↓π 75␈↓.␈α∞ Now,␈α∂consider␈α∞the
␈↓ ↓H␈↓evaluation␈αof␈αthe␈αform␈α␈↓αf[2;3]␈↓.␈α When␈αthe␈αλ-expression␈αis␈αentered,␈αi.e.,␈αwhen␈αwe␈αbind␈αthe␈αevaluated
␈↓ ↓H␈↓arguments␈α
(␈↓α2␈↓␈αand␈α
␈↓α3␈↓)␈α
to␈αthe␈α
λ-variables␈α
(␈↓αx␈↓␈αand␈α
␈↓αy␈↓),␈α
a␈αnew␈α
local␈α
table␈α(E␈↓β1␈↓)␈α
is␈α
set␈αup␈α
with␈α
an␈αaccess␈α
link
␈↓ ↓H␈↓to␈α∂E␈↓β0␈↓.␈α⊂ Entries␈α∂reflecting␈α∂the␈α⊂binding␈α∂of␈α⊂the␈α∂λ-variables␈α∂are␈α⊂made␈α∂in␈α∂E␈↓β1␈↓␈α⊂and␈α∂evaluation␈α⊂of␈α∂the
␈↓ ↓H␈↓λ-body is begun.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 75␈↓ Note that we really mean "representation of lambda definition".
␈↓ ↓H␈↓␈↓↓118 Evaluation␈↓ 43.8␈↓
␈↓ ↓H␈↓The flow of symbol table creation is:
␈↓ ↓H␈↓␈↓ β(␈↓ βX␈↓αf[2;3]␈↓ ¬x␈↓ ε(x␈↓π2␈↓α + y␈↓
␈↓ ↓H␈↓␈↓ β(␈↓ βXE␈↓β0␈↓␈↓ ∧λ␈↓ ¬x␈↓ ε(E␈↓β1␈↓␈↓ λ_␈↓ λh␈↓ _E␈↓β0␈↓
␈↓ ↓H␈↓␈↓ β(␈↓ βX| /␈↓ ∧λ␈↓ ¬x␈↓ ε(| E␈↓β0␈↓␈↓ λ_␈↓ λh␈↓ _| /
␈↓ ↓H␈↓␈↓ β(␈↓ βX______ =>␈↓ ¬x______␈↓ λ_=>␈↓ λh______ return with value ␈↓α7␈↓.
␈↓ ↓H␈↓␈↓ β( ␈↓αf␈↓ βX| λ[[x;y] x␈↓π2␈↓α + y]␈↓␈↓ ¬x␈↓αx␈↓ ε(| 2␈↓ λ_␈↓ λhf␈↓ _| λ[[x;y] ... ]
␈↓ ↓H␈↓α␈↓ β(␈↓ βX␈↓ ∧λ␈↓ ¬x y␈↓ ε(| 3␈↓
␈↓ ↓H␈↓Compare this sequence to the example on page 107.
␈↓ ↓H␈↓The sequence of tables corresponds to the evaluation sequence:
␈↓ ↓H␈↓␈↓ ∧*␈↓αeval[␈↓
R␈↓∞( ␈↓αf[2;3] ␈↓∞)␈↓α; ␈↓
R␈↓∞( ␈↓α{<f , λ[[x;y] x␈↓π2␈↓α +y]>} ␈↓∞)␈↓α]
␈↓ ↓H␈↓α␈↓ εH↓
␈↓ ↓H␈↓α␈↓ βMeval[␈↓
R␈↓∞( ␈↓αx␈↓π2␈↓α + y ␈↓∞)␈↓α; ␈↓
R␈↓∞( ␈↓α{<x, 2>, <y, 3>, <f , λ[[x;y] x␈↓π2␈↓α +y]>} ␈↓∞)␈↓α]
␈↓ ↓H␈↓α␈↓ εH↓
␈↓ ↓H␈↓α␈↓ εI7␈↓
␈↓ ↓H␈↓You␈α∂should␈α⊂realize␈α∂that␈α∂the␈α⊂Weizenbaum␈α∂environments␈α∂are␈α⊂just␈α∂another␈α∂abstract␈α⊂data␈α∂structure
␈↓ ↓H␈↓with␈α∪associated␈α∩constructors,␈α∪selectors,␈α∩and␈α∪recognizers.␈α∩They␈α∪may␈α∩be␈α∪expressed␈α∩as␈α∪LISP␈α∩data
␈↓ ↓H␈↓structures␈αwithout␈αmuch␈αdifficulty.␈αThe␈αonly␈αdifference␈αhere␈αis␈αthat␈αthe␈αenvironments␈αhappen␈αto␈α
be
␈↓ ↓H␈↓more␈α∂meaningful␈α⊂when␈α∂described␈α⊂graphically␈α∂than␈α∂if␈α⊂they␈α∂were␈α⊂specified␈α∂by␈α⊂their␈α∂manipulating
␈↓ ↓H␈↓functions.␈α
See␈α
the␈αproblem␈α
on␈α
page 120.␈α
Graphical␈αrepresentations␈α
and␈α
languages␈α
are␈αan␈α
important
␈↓ ↓H␈↓tool in data structure programming; we will say a bit more about this in Section 5.4.
␈↓ ↓H␈↓␈↓↓3.8␈↓ λEnvironments and Bindings 119␈↓
␈↓ ↓H␈↓The␈α∀execution␈α∪of␈α∀␈↓αfact[3]␈↓␈α∀on␈α∪page 108␈α∀results␈α∪in␈α∀a␈α∀more␈α∪interesting␈α∀example.␈α∀The␈α∪following
␈↓ ↓H␈↓discussion should be read in conjunction with that description␈↓π 76␈↓.
␈↓"␈↓ ↓H␈↓␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓
⊃␈↓
␈↓"␈↓ ↓H␈↓␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓
εα→ ␈↓α6␈↓
␈↓"␈↓ ↓H␈↓
␈↓ αH␈↓ β_␈↓αfact[3]␈↓ ∧8␈↓ ¬λ␈↓ ¬X[x=0→ ...]␈↓ εx␈↓ πH␈↓ λ_*[x;fact[x-1]]␈↓ H␈↓
ε←⊃␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓E␈↓β0␈↓␈↓ ∧8␈↓ ¬λ␈↓ ¬XE␈↓β1␈↓␈↓ εx␈↓ πH␈↓ λ_E␈↓β1␈↓␈↓ H␈↓
~ ~␈↓
␈↓"␈↓ ↓H␈↓␈↓ αH␈↓ β_| /␈↓ ∧8␈↓ ¬λ␈↓ ¬X| E␈↓β0␈↓␈↓ εx␈↓ πH␈↓ λ_| E␈↓β0␈↓␈↓ H␈↓
$ ↑␈↓
␈↓"␈↓ ↓H␈↓␈↓ αH_______␈↓ ∧8=>␈↓ ¬λ_______␈↓ εx=>␈↓ πH_______ =>␈↓ H␈↓ h␈↓α2␈↓
␈↓"␈↓ ↓H␈↓␈↓ αH␈↓αfact␈↓ β_| λ[[x][x=0→1;...]␈↓ ¬λ x␈↓ ¬X| 3␈↓ εx␈↓ πH x␈↓ λ_| 3␈↓ H␈↓ h␈↓
↑␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓
⊃ ~␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓
ε→$␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_fact[2]␈↓ ∧8␈↓ ¬λ␈↓ ¬X[x=0→ ...]␈↓ εx␈↓ πH␈↓ λ_*[x;fact[x-1]]␈↓ H␈↓
~␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓E␈↓β1␈↓␈↓ ∧8␈↓ ¬λ␈↓ ¬XE␈↓β2␈↓␈↓ εx␈↓ πH␈↓ λ_E␈↓β2␈↓␈↓ H␈↓
ε←⊃␈↓
␈↓"␈↓ ↓H␈↓␈↓ αH␈↓ β_| E␈↓β0␈↓␈↓ ∧8␈↓ ¬λ␈↓ ¬X| E␈↓β1␈↓␈↓ εx␈↓ πH␈↓ λ_| E␈↓β1␈↓␈↓ H␈↓
$ ↑␈↓
␈↓"␈↓ ↓H␈↓ =>␈↓ αH_______␈↓ ∧8=>␈↓ ¬λ_______␈↓ εx=>␈↓ πH_______ =>␈↓ H␈↓ h␈↓α1␈↓
␈↓"␈↓ ↓H␈↓␈↓ αH␈↓α x␈↓ β_| 3␈↓ ∧8␈↓ ¬λ x␈↓ ¬X| 2␈↓ εx␈↓ πH x␈↓ λ_| 2␈↓ H␈↓ h␈↓
↑␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓ h␈↓
~␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓
⊃ ~␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓
ε→$␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_fact[1]␈↓ ∧8␈↓ ¬λ␈↓ ¬X[x=0→ ...]␈↓ εx␈↓ πH␈↓ λ_*[x;fact[x-1]]␈↓ H␈↓
~␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓E␈↓β2␈↓␈↓ ∧8␈↓ ¬λ␈↓ ¬XE␈↓β3␈↓␈↓ εx␈↓ πH␈↓ λ_E␈↓β3␈↓␈↓ H␈↓
ε←⊃␈↓
␈↓"␈↓ ↓H␈↓␈↓ αH␈↓ β_| E␈↓β1␈↓␈↓ ∧8␈↓ ¬λ␈↓ ¬X| E␈↓β2␈↓␈↓ εx␈↓ πH␈↓ λ_| E␈↓β2␈↓␈↓ H␈↓
$ ~␈↓
␈↓"␈↓ ↓H␈↓ =>␈↓ αH_______␈↓ ∧8=>␈↓ ¬λ_______␈↓ εx=>␈↓ πH_______ =>␈↓ H␈↓ h␈↓
~␈↓
␈↓"␈↓ ↓H␈↓␈↓ αH␈↓α x␈↓ β_| 2␈↓ ∧8␈↓ ¬λ x␈↓ ¬X| 1␈↓ εx␈↓ πH x␈↓ λ_| 1␈↓ H␈↓ h␈↓
↑␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓ h1
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓ h␈↓
↑␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓ ∧8␈↓ ¬λ␈↓ ¬X␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓ h␈↓
~␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_fact[0]␈↓ ∧8␈↓ ¬λ␈↓ ¬X[x=0→1; ...]␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓
⊃ ~␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_E␈↓β3␈↓α␈↓ ∧8␈↓ ¬λ␈↓ ¬XE␈↓β4␈↓α␈↓ εx␈↓ πH␈↓ λ_␈↓ H␈↓
~ ↑␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH␈↓ β_| E␈↓β2␈↓α␈↓ ∧8␈↓ ¬λ␈↓ ¬X| E␈↓β3␈↓α␈↓ εx␈↓ πH␈↓ λ_␈↓send␈↓α␈↓ H␈↓
~ ~␈↓α
␈↓"␈↓ ↓H␈↓α =>␈↓ αH_______␈↓ ∧8=>␈↓ ¬λ_______␈↓ εx=> 1␈↓ πH␈↓ λ_ 1␈↓ H␈↓
ε→$␈↓α
␈↓"␈↓ ↓H␈↓α␈↓ αH x␈↓ β_| 1␈↓ ∧8␈↓ ¬λ x␈↓ ¬X| 0␈↓ εx␈↓ πH␈↓ λ_␈↓back up␈↓ H␈↓
$␈↓
␈↓ ↓H␈↓At␈α∞the␈α∞end␈α∞of␈α∞the␈α∞first␈α∞line␈α∞we␈α∞are␈α∞faced␈α∞with␈α∞the␈α∞evaluation␈α∞of␈α∞␈↓α*[x;fact[x-1]]␈↓.␈α∞This␈α∞requires␈α∞the
␈↓ ↓H␈↓evaluation␈αof␈αthe␈α
arguments␈αto␈α*;␈αthis␈α
is␈αdone␈αby␈α
␈↓αevlis␈↓.␈αFirst␈α␈↓αx␈↓␈αis␈α
evaluated␈αand␈αsaved␈↓π 77␈↓,␈α
then␈αthe
␈↓ ↓H␈↓evaluation␈α
of␈α
␈↓αfact[x-1]␈↓␈α
is␈α
begun␈αusing␈α
environment␈α
E␈↓β1␈↓.␈α
In␈α
E␈↓β1␈↓,␈α
␈↓αx-1␈↓␈αgives␈α
␈↓α2␈↓␈α
and␈α
we␈α
find␈αthe␈α
definition
␈↓ ↓H␈↓of␈α␈↓αfact␈↓␈α
in␈αE␈↓β0␈↓.␈α
In␈αthe␈α
second␈αline␈α
we␈αset␈α
up␈αE␈↓β2␈↓␈α
and␈αevaluate␈α
␈↓αfact[2]␈↓.␈αAnalogous␈α
situations␈αoccur␈α
until
␈↓ ↓H␈↓the␈α
fourth␈αline;␈α
at␈αthis␈α
time␈αwe␈α
suddenly␈α
find␈αourselves␈α
in␈αE␈↓β4␈↓␈α
with␈α␈↓αx␈↓␈α
bound␈αto␈α
␈↓α0␈↓.␈α
The␈αexpression
␈↓ ↓H␈↓␈↓αx=0␈↓␈α⊃is␈α⊂satisfied␈α⊃and␈α⊃we␈α⊂start␈α⊃back␈α⊃up␈α⊂the␈α⊃right␈α⊂margin␈α⊃to␈α⊃conclude␈α⊂the␈α⊃nested␈α⊃evaluations␈α⊂of
␈↓ ↓H␈↓␈↓α*[x;fact[x-1]]␈↓. This process finally terminates at the top, returning a value ␈↓α6␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 76␈↓ The layout of this example is due to R. Davis.
␈↓ ↓H␈↓␈↓π 77␈↓␈α∞This␈α∞saved␈α∞information␈α∂is␈α∞not␈α∞explicitly␈α∞represented␈α∞in␈α∂these␈α∞pictures␈α∞or␈α∞in␈α∂the␈α∞Weizenbaum
␈↓ ↓H␈↓diagrams.
␈↓ ↓H␈↓␈↓↓120 Evaluation␈↓ 43.8␈↓
␈↓ ↓H␈↓Notice␈αin␈αthis␈αexample␈αthat␈αwe␈αwill␈αget␈αthe␈α
correct␈αbinding␈αof␈α␈↓αx␈↓␈αlocally.␈α It␈αis␈αimportant␈αto␈αnote␈α
that
␈↓ ↓H␈↓the␈α⊂occurrence␈α∂of␈α⊂␈↓αfact␈↓␈α∂within␈α⊂the␈α∂body␈α⊂of␈α∂the␈α⊂definition␈α∂of␈α⊂␈↓αfact␈↓␈α∂is␈α⊂␈↓↓global␈↓.␈α∂We␈α⊂find␈α⊂the␈α∂correct
␈↓ ↓H␈↓binding␈αfor␈α␈↓αfact␈↓␈αby␈αsearching␈αthe␈αaccess␈αchain.␈α We␈αmust␈αsearch␈αthe␈αaccess␈αchain␈αeven␈αthough␈α␈↓αfact␈↓
␈↓ ↓H␈↓is␈α∞global.␈α∞ We␈α∞cannot␈α∞shortcut␈α∂the␈α∞search␈α∞by␈α∞simply␈α∞looking␈α∂in␈α∞E␈↓β0␈↓.␈α∞A␈α∞variable␈α∞might␈α∂have␈α∞been
␈↓ ↓H␈↓rebound in an enclosing environment and it would be that binding we should discover.
␈↓ ↓H␈↓As␈α~a␈α~final␈α→example␈α~showing␈α~access␈α→to␈α~non-local␈α~variable␈α→bindings␈α~consider␈α~␈↓αf[3]␈↓␈α→where
␈↓ ↓H␈↓␈↓αf <= λ[[x] g[2]]␈↓ and ␈↓αg <= λ[[y] x+y]␈↓.
␈↓ ↓H␈↓␈↓ βH␈↓ βx␈↓αf[3]␈↓ ∧H␈↓ ε_␈↓ ε8g[2]␈↓ λ8␈↓ λ␈↓ 8x + y ....
␈↓ ↓H␈↓α␈↓ βH␈↓ βxE␈↓β0␈↓α␈↓ ∧H␈↓ ε_␈↓ ε8E␈↓β1␈↓α␈↓ λ8␈↓ λ␈↓ 8E␈↓β2␈↓α ....
␈↓ ↓H␈↓α␈↓ βH␈↓ βx| /␈↓ ∧H␈↓ ε_␈↓ ε8| E␈↓β0␈↓α␈↓ λ8␈↓ λ␈↓ 8| E␈↓β1␈↓α
␈↓ ↓H␈↓α␈↓ βH______␈↓ ∧H =>␈↓ ε_______␈↓ λ8=>␈↓ λ______␈↓
λ ......
␈↓ ↓H␈↓α␈↓ βH f␈↓ βx| λ[[x] g[2]]␈↓ ε_x␈↓ ε8| 3␈↓ λ8␈↓ λy␈↓ 8| 2 ...
␈↓ ↓H␈↓α␈↓ βH g␈↓ βx| λ[[y] x+y]
␈↓ ↓H␈↓Notice␈αthat␈αwhen␈αwe␈αattempt␈αto␈αevaluate␈α␈↓αx␈α+␈αy␈↓␈αwe␈αfind␈α␈↓αy␈↓␈αhas␈αa␈αlocal␈αvalue,␈αbut␈αwe␈αmust␈αlook␈αdown
␈↓ ↓H␈↓the access chain to find a binding for ␈↓αx␈↓.
␈↓ ↓H␈↓The scheme for using Weizenbaum environments for the current LISP subset is:
␈↓ ↓H␈↓␈↓ α_When␈αdoing␈αa␈αλ-binding,␈αset␈αup␈αa␈αnew␈α
E␈↓βnew␈↓␈αwith␈αthe␈αλ-variables␈αas␈αthe␈αlocal␈αvariable␈α
entries
␈↓ ↓H␈↓␈↓ α_and␈α
the␈α
values␈α
of␈α
the␈αarguments␈α
as␈α
the␈α
corresponding␈α
value␈αentries.␈α
The␈α
access␈α
slot␈α
of␈αthe
␈↓ ↓H␈↓␈↓ α_new␈α⊗E␈↓βnew␈↓␈α⊗points␈α∃to␈α⊗the␈α⊗previous␈α⊗symbol␈α∃table.␈α⊗ The␈α⊗evaluation␈α∃of␈α⊗the␈α⊗body␈α⊗of␈α∃the
␈↓ ↓H␈↓␈↓ α_λ-expression␈αtakes␈αplace␈αusing␈αthe␈α
new␈αtable;␈αwhen␈αa␈αlocal␈α
variable␈αis␈αaccessed␈αwe␈αfind␈α
it␈αin
␈↓ ↓H␈↓␈↓ α_E␈↓βnew␈↓; when a non-local variable occurs, we chase the access chain to find its value.
␈↓ ↓H␈↓␈↓ α_When␈α_the␈α_evaluation␈α_of␈α↔the␈α_body␈α_is␈α_completed,␈α↔E␈↓βnew␈↓␈α_disappears␈α_and␈α_the␈α↔previous
␈↓ ↓H␈↓␈↓ α_environment is restored.
␈↓ ↓H␈↓You␈α∂should␈α∂convince␈α∂yourself␈α∂that␈α∂the␈α∂current␈α∂access-␈α∂and␈α∂binding-scheme␈α∂espoused␈α∂by␈α∂LISP␈α∞is
␈↓ ↓H␈↓faithfully described in these diagrams.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓␈α
By␈αnow␈α
you␈αshould␈α
realize␈αthat␈α
environments␈α
really␈αare␈α
a␈αclass␈α
of␈αabstract␈α
data␈α
structures:␈αthey
␈↓ ↓H␈↓should␈αhave␈αconstructors,␈αselectors,␈αand␈αrecognizers.␈α To␈αhelp␈αdiscover␈αwhat␈αa␈αset␈αof␈αsuch␈αfunctions
␈↓ ↓H␈↓might␈α⊃be,␈α⊃give␈α⊃a␈α⊂representation␈α⊃for␈α⊃Weizenbaum␈α⊃environments␈α⊂and␈α⊃write␈α⊃new␈α⊃versions␈α⊃of␈α⊂the
␈↓ ↓H␈↓symbol␈α∪table␈α∪manipulating␈α∪functions,␈α∪␈↓αlookup␈↓␈α∪and␈α∪␈↓αmkenv␈↓,␈α∪which␈α∪will␈α∪operate␈α∀on␈α∪Weizenbaum
␈↓ ↓H␈↓environments. See page 109.
␈↓ ↓H␈↓␈↓↓3.9␈↓
@␈↓αlabel␈↓↓ 121␈↓α
␈↓ ↓H␈↓␈↓ ε_␈↓↓3.9 ␈↓αlabel␈↓↓␈↓α
␈↓ ↓H␈↓One␈α⊃effect␈α⊃of␈α⊂placing␈α⊃"λ"␈α⊃and␈α⊃a␈α⊂list␈α⊃of␈α⊃λ-variables␈α⊂in␈α⊃front␈α⊃of␈α⊃an␈α⊂expresson␈α⊃is␈α⊃to␈α⊃bind␈α⊂those
␈↓ ↓H␈↓variables␈αwhich␈αappear␈αin␈αthe␈αλ-list.␈αAll␈αother␈αvariables␈αappearing␈αin␈αthe␈αexpression␈αare␈αnon-local.
␈↓ ↓H␈↓For example, ␈↓αf␈↓ is non-local in the following:
␈↓ ↓H␈↓␈↓ ∧L␈↓αf <= λ[[x][zerop[x] → 1; ␈↓
t␈↓α → *[x;f[x-1]]] ].␈↓
␈↓ ↓H␈↓Clearly␈αour␈αintention␈αis␈αthat␈αthe␈α␈↓αf␈↓␈αappearing␈αto␈αthe␈αright␈αof␈α"<="␈αis␈αthe␈αsame␈αas␈αthe␈α␈↓αf␈↓␈αappearing␈αto
␈↓ ↓H␈↓the left of "<=".
␈↓ ↓H␈↓This␈αhas␈αnot␈αbeen␈αa␈αproblem␈αfor␈αus.␈α We␈αhave␈αsimply␈αpre-loaded␈αthe␈αsymbol␈αtable,␈αbinding␈α␈↓αf␈↓␈αto␈αits
␈↓ ↓H␈↓definition␈α(or␈αvalue);␈αsee␈αpage 108.␈α
LISP␈αhas␈αa␈αmore␈αelegant␈αdevice␈α
for␈αthis␈αbinding.␈αIt␈αis␈αcalled␈α
the
␈↓ ↓H␈↓␈↓αlabel␈↓ operator and is written:
␈↓ ↓H␈↓␈↓ ¬
␈↓αlabel[␈↓<identifier>;<function>] .
␈↓ ↓H␈↓Its␈αevaluation␈αhas␈α
the␈αeffect␈αof␈α
binding␈αthe␈α<identifier>␈αto␈α
the␈α<function>.␈α The␈α
value␈αconstructed
␈↓ ↓H␈↓by␈αexecuting␈α
a␈α␈↓αlabel␈↓-expression␈αis␈α
a␈αrepresentation␈αof␈α
a␈αfunction␈αwith␈α
name␈α<identifier>␈α
and␈αbody
␈↓ ↓H␈↓<function>.
␈↓ ↓H␈↓For example, a proper definition of ␈↓αfact␈↓ is:
␈↓ ↓H␈↓␈↓ ∧λ␈↓αlabel[fact; λ[[x][eq[x;0] → 1; ␈↓
t␈↓α → *[x;fact[sub1[x]]]]]]␈↓
␈↓ ↓H␈↓To include ␈↓αlabel␈↓ in the LISP syntax add:
␈↓ ↓H␈↓␈↓ ∧=<function>::= ␈↓αlabel␈↓[<identifier>;<function>]
␈↓ ↓H␈↓and the S-expr translation of the ␈↓αlabel␈↓ construct should naturally be:
␈↓ ↓H␈↓␈↓ ∧!␈↓
R␈↓∞( ␈↓αlabel[f;fn] ␈↓∞)␈↓α = (LABEL ␈↓
R␈↓∞( ␈↓αf ␈↓∞)␈↓α ␈↓
R␈↓∞( ␈↓αfn ␈↓∞)␈↓α)␈↓
␈↓ ↓H␈↓Note that ␈↓αlabel␈↓ is a special form, not a call-by-value function.
␈↓ ↓H␈↓Since␈αthe␈α␈↓αlabel␈↓␈αoperator␈αcreates␈αa␈αfunction,␈α
it␈αshould␈αappear␈αin␈αthe␈αfunction␈αposition␈αof␈α
a␈αfunction
␈↓ ↓H␈↓application.␈α∂ A␈α∂typical␈α∂application␈α∞of␈α∂the␈α∂␈↓αlabel␈↓␈α∂construct,␈α∞say␈α∂␈↓αlabel[f;λ[[x]␈α∂␈↓λx␈↓α[x]]][A]␈↓,␈α∂results␈α∂in␈α∞the
␈↓ ↓H␈↓following environmental picture when we get ready to evaluate ␈↓λx␈↓α[x]␈↓:
␈↓ ↓H␈↓␈↓ αλ␈↓αlabel[f;λ[[x] ␈↓λx␈↓α[x]]][A]␈↓␈↓ ∧x␈↓ ¬H␈↓λx␈↓α[x]␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓ βλE␈↓β0␈↓␈↓ ∧x␈↓ ¬H␈↓ ¬xE␈↓β1␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓ βλ | /␈↓ ∧x␈↓ ¬H␈↓ ¬x| E␈↓β0␈↓
␈↓ ↓H␈↓␈↓ αλ ___________␈↓ ∧x=> ...␈↓ ¬H______
␈↓ ↓H␈↓␈↓ αλ␈↓ βλ |␈↓ ∧x␈↓ ¬H␈↓αf␈↓ ¬x| λ[[x] ␈↓λx␈↓α[x]]
␈↓ ↓H␈↓α␈↓ αλ␈↓ βλ␈↓ ∧x␈↓ ¬Hx␈↓ ¬x|A
␈↓ ↓H␈↓␈↓↓122 Evaluation␈↓ 53.9␈↓
␈↓ ↓H␈↓Notice␈αthat␈αthe␈αdefinition␈αdoes␈αnot␈αappear␈αin␈αthe␈αglobal␈αtable␈αE␈↓β0␈↓;␈αwe␈αuse␈α␈↓αlabel␈↓␈αto␈α
create␈αtemporary
␈↓ ↓H␈↓function␈α∂definitions.␈α∞ These␈α∂definitions␈α∞disappear␈α∂when␈α∂the␈α∞environment␈α∂in␈α∞which␈α∂the␈α∂␈↓αlabel␈↓␈α∞was
␈↓ ↓H␈↓executed␈αis␈αno␈αlonger␈αaccessible␈α
to␈αthe␈αcomputation.␈α Thus␈αwithin␈α
the␈αevaluation␈αof␈αthe␈αbody␈α␈↓λx␈↓α[x]␈↓␈α
a
␈↓ ↓H␈↓recursive␈α
call␈αon␈α
␈↓αf␈↓␈αwill␈α
refer␈αto␈α
the␈αdefinition␈α
of␈α
␈↓αf␈↓␈αlocated␈α
in␈αE␈↓β1␈↓␈α
so␈αlong␈α
as␈α␈↓αf␈↓␈α
is␈αnot␈α
rebound␈α
in␈α␈↓λx␈↓;
␈↓ ↓H␈↓once␈αwe␈αhave␈α
completed␈αthe␈αcomputation␈α
initialized␈αin␈αE␈↓β0␈↓␈αthe␈α
definition␈αof␈α␈↓αf␈↓␈α
will␈αdisappear.␈α If␈α␈↓αf␈↓␈α
is
␈↓ ↓H␈↓not recursive, then the use of ␈↓αlabel␈↓ is unnecessary; an anonymous function application will suffice.
␈↓ ↓H␈↓What␈α
about␈α∞statements␈α
like␈α
"evaluate␈α∞␈↓αg[A;B]␈↓␈α
where␈α
␈↓αg <= λ[[x;y] ... f[u;v] ...]␈↓␈α∞and␈α
␈↓αf <= λ[[x;y] ... ]␈↓."?
␈↓ ↓H␈↓␈↓αlabel␈↓␈α⊃defines␈α⊂only␈α⊃one␈α⊂function;␈α⊃we␈α⊂may␈α⊃not␈α⊂say␈α⊃␈↓αlabel[f,g; ... ]␈↓.␈α⊂ What␈α⊃we␈α⊂␈↓↓can␈↓␈α⊃do␈α⊂is␈α⊃embed␈α⊂the
␈↓ ↓H␈↓␈↓αlabel␈↓-definition for ␈↓αf␈↓ within the ␈↓αlabel␈↓-definition for ␈↓αg␈↓␈↓π 78␈↓. Thus:
␈↓ ↓H␈↓α␈↓ ∧3label[g; λ[[x;y] ... label[f; λ[[x;y] ... ]][u;v] ...]]␈↓
␈↓ ↓H␈↓Several␈α
languages␈αallow␈α
a␈αsimpler␈α
notation␈αfor␈α
giving␈αmutually␈α
recursive␈αdefinitions;␈α
see␈α[Rey 72],
␈↓ ↓H␈↓[Hew 74], or [Sus 75].
␈↓ ↓H␈↓It␈α⊃can␈α⊃be␈α⊃shown␈α⊂that␈α⊃the␈α⊃␈↓αlabel␈↓␈α⊃operator␈α⊂is␈α⊃superfluous;␈α⊃the␈α⊃same␈α⊂effect␈α⊃can␈α⊃be␈α⊃obtained␈α⊃by␈α⊂a
␈↓ ↓H␈↓complicated␈α∪λ-binding.␈α∪ However␈α∪our␈α∀point␈α∪here␈α∪is␈α∪not␈α∪to␈α∀be␈α∪"minimal",␈α∪but␈α∪to␈α∀be␈α∪"useful".
␈↓ ↓H␈↓Implementations␈α⊗of␈α⊗LISP␈α⊗offer␈α⊗other␈α⊗definitional␈α⊗facilities,␈α⊗with␈α⊗"<="␈α⊗having␈α⊗the␈α⊗effect␈α∃of
␈↓ ↓H␈↓permanently establishing the definition in E␈↓β0␈↓.
␈↓ ↓H␈↓The␈αapparent␈αsimplicity␈αof␈αthe␈α␈↓αlabel␈↓␈αoperator␈αis␈αpartly␈αdue␈αto␈αmisconception␈αand␈αpartly␈αdue␈α
to␈αthe
␈↓ ↓H␈↓restrictions␈α∞placed␈α∞on␈α∂the␈α∞current␈α∞subset␈α∂of␈α∞LISP.␈α∞␈↓αlabel␈↓␈α∞appears␈α∂to␈α∞be␈α∞a␈α∂rather␈α∞weak␈α∞form␈α∂of␈α∞an
␈↓ ↓H␈↓assignment␈α∪statement.␈α∩When␈α∪we␈α∩extend␈α∪LISP␈α∩to␈α∪include␈α∩assignments␈α∪we␈α∩can␈α∪show␈α∪that␈α∩such
␈↓ ↓H␈↓interpretation of ␈↓αlabel␈↓ is insufficient.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Show one way to change ␈↓αeval␈↓ to handle ␈↓αlabel␈↓.
␈↓ ↓H␈↓II. Express the definition of ␈↓αreverse␈↓ given on page 46 using ␈↓αlabel␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 78␈↓ Indeed ␈↓↓every␈↓ occurrence of ␈↓αf␈↓ must be replaced by the ␈↓αlabel[f;...]␈↓ construct.
␈↓ ↓H␈↓␈↓↓3.9␈↓
@␈↓αlabel␈↓↓ 123␈↓α
␈↓ ↓H␈↓III. Evaluate the following:
␈↓ ↓H␈↓α␈↓ ¬6λ[[y] label[fn;fn␈↓β2␈↓α][␈↓
f␈↓α]] [␈↓
f␈↓α]
␈↓ ↓H␈↓α␈↓where:␈↓α
␈↓ ↓H␈↓α␈↓ ∧dfn␈↓β2␈↓α <= λ[[x][y → 1; x → 2; ␈↓
t␈↓α → fn␈↓β1␈↓α[␈↓
t␈↓α]]
␈↓ ↓H␈↓α␈↓ ¬Zfn␈↓β1␈↓α <= λ[[y] fn[y]]
␈↓ ↓H␈↓␈↓ βz␈↓↓3.10 Functional Arguments and Functional Values␈↓
␈↓ ↓H␈↓Recall our discussion of :
␈↓ ↓H␈↓α␈↓ β-eval[(F 2 3);((F . (LAMBDA (X Y) (PLUS (EXPT X 2) Y))))].
␈↓ ↓H␈↓We now know this is equivalent to:
␈↓ ↓H␈↓␈↓ β∧␈↓αeval[((LABEL F (LAMBDA (X Y) (PLUS (EXPT X 2) Y))) 2 3);( )]␈↓.
␈↓ ↓H␈↓In␈αeither␈αcase,␈αthe␈αeffect␈αis␈αto␈αbind␈αthe␈αname␈α␈↓αf␈↓␈αto␈αthe␈αλ-expression.␈α Binding␈αalso␈αoccurs␈αwhen␈α␈↓αf␈↓␈αis
␈↓ ↓H␈↓called:␈α
we␈α
bind␈α
␈↓αx␈↓␈αto␈α
␈↓α2␈↓,␈α
and␈α
␈↓αy␈↓␈αto␈α
␈↓α3␈↓.␈α
In␈α
the␈α
latter␈αcase␈α
we␈α
are␈α
binding␈αsimple␈α
values;␈α
in␈α
the␈αformer␈α
we
␈↓ ↓H␈↓are␈α
binding␈αfunctions␈α
as␈αvalues.␈α
We␈α
have␈αdecided␈α
that␈αthe␈α
necessary␈αingredients␈α
to␈α
characterize␈αa
␈↓ ↓H␈↓functional␈α⊃value␈↓π 79␈↓␈α⊂are␈α⊃a␈α⊂representation␈α⊃of␈α⊂the␈α⊃formal␈α⊂parameters,␈α⊃and␈α⊂a␈α⊃representation␈α⊃of␈α⊂the
␈↓ ↓H␈↓expression␈αdescribed␈αin␈αthe␈αbody␈αof␈αthe␈αfunction.␈α In␈αthis␈αsection␈αwe␈αwill␈αexamine␈αthe␈αadequacy␈αof
␈↓ ↓H␈↓that decision. We begin informally with a few examples.
␈↓ ↓H␈↓Assume␈α∂we␈α∂have␈α∂a␈α∂list␈α∂␈↓αl␈↓␈α∞of␈α∂dotted-pairs␈α∂␈↓λα␈↓β1␈↓ ,..., ␈↓λα␈↓βn␈↓,␈α∂and␈α∂we␈α∂wish␈α∞to␈α∂form␈α∂a␈α∂new␈α∂list␈α∂of␈α∂the␈α∞form
␈↓ ↓H␈↓␈↓α(car[␈↓λα␈↓β1␈↓α] ... car[␈↓λα␈↓βn␈↓α])␈↓.␈α
That␈α
is␈αwe␈α
wish␈α
to␈αapply␈α
␈↓αcar␈↓␈α
to␈αeach␈α
of␈α
the␈αelements␈α
of␈α
␈↓αl␈↓.␈αSuch␈α
a␈α
function␈αis
␈↓ ↓H␈↓easy to write:
␈↓ ↓H␈↓␈↓ β⊃␈↓αcarfirst <= λ[[l][null[l] → ( ); ␈↓
t␈↓α → concat[car[first[l]];carfirst[rest[l]]]]].␈↓
␈↓ ↓H␈↓Now␈αsuppose␈αwe␈αwish␈αto␈αwrite␈αa␈αmore␈αgeneral␈αfunction,␈αwhich␈αinstead␈αof␈αbeing␈αspecific␈αto␈α␈↓αcar␈↓,␈αwill
␈↓ ↓H␈↓take␈α∀an␈α∃␈↓↓arbitrary␈↓␈α∀unary␈α∀function␈α∃␈↓αf␈↓␈α∀and␈α∃apply␈α∀it␈α∀to␈α∃each␈α∀of␈α∀the␈α∃elements␈α∀of␈α∃␈↓αl␈↓,␈α∀generating
␈↓ ↓H␈↓␈↓α(f[␈↓λα␈↓β1␈↓α], ..., f[␈↓λα␈↓βn␈↓α])␈↓. Such a function could plausibly be defined as follows:
␈↓ ↓H␈↓␈↓ α←␈↓αmapfirst <= λ[[fn;l][null[l] → ( ); ␈↓
t␈↓α → concat[fn[first[l]];mapfirst[fn;rest[l]]]]].␈↓
␈↓ ↓H␈↓Thus the first calculation we requested above could be expressed as:
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 79␈↓␈α∂It␈α∂would␈α⊂be␈α∂better␈α∂to␈α∂call␈α⊂these␈α∂constructs␈α∂"procedure␈α∂values"␈α⊂since␈α∂we␈α∂will␈α∂take␈α⊂a␈α∂decidedly
␈↓ ↓H␈↓algorithmic interpretation of them.
␈↓ ↓H␈↓␈↓↓124 Evaluation␈↓ )3.10␈↓
␈↓ ↓H␈↓␈↓ ¬↓␈↓αmapfirst[car;l]␈↓ ....... or could it?
␈↓ ↓H␈↓Recalling␈α⊃LISP's␈α⊃penchant␈α⊂for␈α⊃call-by-value␈α⊃evaluation,␈α⊃we␈α⊂might␈α⊃believe␈α⊃that␈α⊃the␈α⊂computation
␈↓ ↓H␈↓would␈αnot␈αbe␈αdone␈αas␈αexpected.␈αWe␈αdo␈α␈↓↓not␈↓␈αwant␈αthe␈αargument␈α␈↓αcar␈↓␈αevaluated␈αto␈αproduce␈αan␈αS-expr
␈↓ ↓H␈↓value;␈α
rather,␈α
we␈α
want␈αits␈α
evaluation␈α
to␈α
produce␈α
a␈αrepresentation␈α
of␈α
a␈α
primitive␈α
function,␈αsuitable
␈↓ ↓H␈↓for␈α∀application.␈α∪ There␈α∀are␈α∀two␈α∪ways␈α∀out␈α∪of␈α∀this␈α∀dilemma.␈α∪One␈α∀solution␈α∪is␈α∀to␈α∀suppress␈α∪the
␈↓ ↓H␈↓evaluation␈α
of␈α∞␈↓αcar␈↓,␈α
postponing␈α∞it␈α
until␈α∞the␈α
␈↓αapply␈↓␈α∞function␈α
can␈α∞recognize␈α
that␈α∞a␈α
function␈α∞name␈α
has
␈↓ ↓H␈↓been␈αseen.␈α We␈αhave␈αseen␈αone␈αartifact␈αin␈αLISP␈αto␈αsubdue␈αevaluation:␈αwe␈αcan␈αmake␈αit␈αa␈αconstant␈αby
␈↓ ↓H␈↓␈↓αquote␈↓-ing␈α∩it.␈α⊃Indeed,␈α∩␈↓αmapfirst[quote[car];l]␈α⊃␈↓or␈α∩␈↓αmapfirst[CAR;l]␈α⊃␈↓↓will␈↓␈α∩work.␈α⊃ You␈α∩should␈α⊃convince
␈↓ ↓H␈↓yourself␈α
that␈α
␈↓αmapfirst[CAR;l]␈↓␈αwill␈α
compute␈α
␈↓αcarfirst[l]␈↓;␈α
that␈αexercise␈α
requires␈α
examining␈α
the␈αdetails
␈↓ ↓H␈↓of ␈↓αeval␈↓.
␈↓ ↓H␈↓A␈α⊂second␈α∂solution␈α⊂exists␈α∂and␈α⊂is␈α⊂the␈α∂one␈α⊂we␈α∂will␈α⊂pursue.␈α∂We␈α⊂say␈α⊂that␈α∂the␈α⊂"value"␈α∂of␈α⊂␈↓αcar␈↓␈α⊂␈↓↓is␈↓␈α∂the
␈↓ ↓H␈↓description␈α
of␈α
the␈α
program␈αwhich␈α
computes␈α
␈↓αcar␈↓.␈α
Since␈α
␈↓αcar␈↓␈αis␈α
a␈α
primitive,␈α
that␈α
description␈αis␈α
machine
␈↓ ↓H␈↓code for this specific implementation.
␈↓ ↓H␈↓Before␈α∞going␈α∞on␈α
to␈α∞more␈α∞complex␈α
examples␈α∞it␈α∞would␈α∞be␈α
well␈α∞to␈α∞note␈α
that␈α∞␈↓αmapfirst␈↓␈α∞is␈α∞a␈α
different
␈↓ ↓H␈↓kind␈α
of␈αLISP␈α
function␈αfrom␈α
those␈αwe␈α
have␈α
seen␈αbefore.␈α
The␈αfirst␈α
argument␈αto␈α
␈↓αmapfirst␈↓␈αis␈α
expected
␈↓ ↓H␈↓to␈α⊃be␈α⊂a␈α⊃function.␈α⊂Notice␈α⊃that␈α⊃the␈α⊂argument␈α⊃␈↓αfn␈↓␈α⊂appears␈α⊃in␈α⊃the␈α⊂body␈α⊃of␈α⊂␈↓αmapfirst␈↓␈α⊃in␈α⊃a␈α⊂position
␈↓ ↓H␈↓reserved␈αfor␈αfunctions.␈αTherefore␈αany␈αparameter␈αbound␈αto␈α␈↓αfn␈↓␈αis␈αexpected␈αto␈αbe␈αa␈αfunction.␈αSuch␈αa
␈↓ ↓H␈↓use of a function is called a ␈↓↓functional argument␈↓.
␈↓ ↓H␈↓The␈αfirst␈αtrick␈αwe␈αused␈αabove,␈αrepresenting␈αthe␈αfunctional␈αargument␈α␈↓αcar␈↓␈αas␈αa␈αconstant␈α␈↓αCAR␈↓,␈αcan␈αbe
␈↓ ↓H␈↓applied to other instances of functional arguments.
␈↓ ↓H␈↓Thus the functional argument:
␈↓ ↓H␈↓␈↓ ∧d␈↓αλ[[x] f[g[x]]␈↓ could be represented as,
␈↓ ↓H␈↓␈↓ ¬≡␈↓α(LAMBDA (X) (F (G X))).␈↓
␈↓ ↓H␈↓The␈α⊃trick␈α⊃is␈α⊃called␈α⊃␈↓αQUOTE␈↓-ing␈α⊃the␈α⊂functional␈α⊃argument␈α⊃since␈α⊃the␈α⊃S-expr␈α⊃representation␈α⊃of␈α⊂an
␈↓ ↓H␈↓instance␈αof␈αsuch␈αa␈αconstruct␈αis␈αa␈α
␈↓αQUOTE␈↓-ed␈αexpression.␈α ␈↓αQUOTE␈↓-ing␈αis␈αnot␈αstrictly␈αnecessary␈α
if␈αwe
␈↓ ↓H␈↓follow␈α⊃the␈α⊃second␈α⊃alternative␈α⊃above␈α⊃and␈α∩use␈α⊃the␈α⊃evaluator␈α⊃described␈α⊃in␈α⊃Section 3.5;␈α∩worse␈α⊃yet,
␈↓ ↓H␈↓␈↓αQUOTE␈↓-ing␈α∩is␈α∪also␈α∩not␈α∪sufficient␈α∩to␈α∪capture␈α∩the␈α∩intended␈α∪meaning␈α∩in␈α∪all␈α∩cases␈α∪of␈α∩functional
␈↓ ↓H␈↓parameters.␈α
To␈α
understand␈α
why␈α
␈↓αQUOTE␈↓-ing␈α
is␈α
not␈α
sufficient␈α
we␈α
need␈α
a␈α
slightly␈α
more␈α
complex␈α
set␈α
of
␈↓ ↓H␈↓examples. First we try:
␈↓ ↓H␈↓␈↓ ↓r␈↓αmapfirst[ λ[[x] concat[x;( )]];(A B C D)]␈↓␈↓π 80␈↓. which we expect to evaluate to ␈↓α((A) (B) (C) (D)).␈↓
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 80␈↓␈α
Note␈α
that␈α
we␈α
do␈α
not␈α
use␈α
␈↓αquote␈↓.␈α
Some␈α
implementations␈α
do␈α
not␈α
support␈α
this␈α
notation.␈αSome␈α
require
␈↓ ↓H␈↓␈↓αquote␈↓,␈αand␈α
still␈αothers␈αgive␈α
a␈αdifferent␈α
interpretation␈αto␈αunembellished␈α
functions␈αappearing␈αas␈α
actual
␈↓ ↓H␈↓parameters.
␈↓ ↓H␈↓␈↓↓3.10␈↓ ε⊂Functional Arguments and Functional Values 125␈↓
␈↓ ↓H␈↓ ␈↓αmapfirst[ λ[[x] concat[x;( )]]; ..]␈↓ ∧x␈↓ εh[null[l] ...]␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓ βλE␈↓β0␈↓␈↓ ∧x␈↓ εh␈↓ π_E␈↓β1␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓ βλ| /␈↓ ∧x␈↓ εh␈↓ π_| E␈↓β0␈↓
␈↓ ↓H␈↓␈↓ αλ______________␈↓ ∧x=>␈↓ εh______␈↓ λ=> . . .
␈↓ ↓H␈↓␈↓ αλ␈↓αmapfirst␈↓ βλ| λ[[fn;l][null[l]...]]␈↓ ∧x␈↓ εhl␈↓ π_| (A B C D)
␈↓ ↓H␈↓α␈↓ αλ␈↓ βλ␈↓ ∧x␈↓ εhfn␈↓ π_| λ[[x] concat[x;( )]]␈↓
␈↓ ↓H␈↓Since ␈↓αnull[l]␈↓ is false, the problem reduces to:
␈↓ ↓H␈↓␈↓ ∧H␈↓αconcat[fn[first[l]];mapfirst[fn;rest[l]]].␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬HE␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬H| E␈↓β0␈↓
␈↓ ↓H␈↓␈↓ ∧H______________
␈↓ ↓H␈↓␈↓ ∧H ␈↓αl␈↓ ¬H| (A B C D)
␈↓ ↓H␈↓α␈↓ ∧H fn␈↓ ¬H| λ[[x] concat[x;( )]]␈↓
␈↓ ↓H␈↓Since␈α∀we're␈α∃doing␈α∀call-by-value␈α∃we␈α∀have␈α∃to␈α∀evaluate␈α∃the␈α∀arguments␈α∃to␈α∀␈↓αconcat␈↓;␈α∃that␈α∀requires
␈↓ ↓H␈↓evaluating␈α␈↓αfn[first[l]]␈↓.␈αThe␈αvalue␈αof␈α␈↓αl␈↓␈αwe␈αfind␈α
locally␈αand␈αevaluate␈α␈↓αfirst[l]␈↓,␈αgetting␈α␈↓αA␈↓.␈αThe␈αvalue␈α
for
␈↓ ↓H␈↓␈↓αfn␈↓␈α⊃is␈α⊂also␈α⊃found␈α⊃locally,␈α⊂and␈α⊃since␈α⊂it␈α⊃is␈α⊃the␈α⊂representation␈α⊃of␈α⊂a␈α⊃λ-definition,␈α⊃we␈α⊂set␈α⊃up␈α⊃a␈α⊂new
␈↓ ↓H␈↓environment in which to evaluate the body of ␈↓αfn␈↓, binding the λ-variable ␈↓αx␈↓ to ␈↓αA␈↓:
␈↓ ↓H␈↓␈↓ ∧H ␈↓αconcat[x;( )]␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬HE␈↓β2␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬H| E␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ∧H______________
␈↓ ↓H␈↓␈↓ ∧H ␈↓αx␈↓ ¬H| A␈↓
␈↓ ↓H␈↓The␈αexpected␈α
evaluation␈αtakes␈αplace:␈α
␈↓α(A)␈↓␈αis␈αcomputed␈α
and␈αreturned␈αto␈α
environment␈αE␈↓β1␈↓␈αso␈α
that␈αwe
␈↓ ↓H␈↓may continue the evaluation ␈↓αmapfirst[fn;rest[l]]␈↓.
␈↓ ↓H␈↓However, consider the following variant of this last example. Define:
␈↓ ↓H␈↓␈↓ ∧ ␈↓αfoo <= λ[[l] mapfirst[ λ[[x]concat[x;l]]; (A B C D)]␈↓.
␈↓ ↓H␈↓It␈α⊂would␈α⊂seem␈α⊂that␈α∂␈↓αfoo[( )]␈↓␈α⊂should␈α⊂also␈α⊂give␈α∂␈↓α((A) (B) (C) (D))␈↓␈α⊂since␈α⊂␈↓αl␈↓␈α⊂will␈α∂be␈α⊂bound␈α⊂to␈α⊂␈↓α( )␈↓␈α∂and
␈↓ ↓H␈↓therefore the ␈↓αl␈↓ in the functional argument will effectively be ␈↓α( )␈↓.
␈↓ ↓H␈↓␈↓↓126 Evaluation␈↓ )3.10␈↓
␈↓ ↓H␈↓␈↓ ↓H ␈↓αfoo[( )]␈↓ αH mapfirst[ λ[[x] concat[x;l]]; ..]␈↓ π( [null[l] ... ]
␈↓ ↓H␈↓α␈↓ ↓H␈↓ αH␈↓E␈↓β0␈↓␈↓ ∧8␈↓ ¬λ␈↓ ¬8E␈↓β1␈↓␈↓ π(␈↓ πx␈↓ λ(E␈↓β2␈↓
␈↓ ↓H␈↓␈↓ ↓H␈↓ αH | /␈↓ ∧8␈↓ ¬λ␈↓ ¬8| E␈↓β0␈↓␈↓ π(␈↓ πx␈↓ λ(| E␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ↓H______________␈↓ ∧8=>␈↓ ¬λ______␈↓ π(=>␈↓ πx______ => ...
␈↓ ↓H␈↓␈↓ ↓H ␈↓αfoo␈↓ αH| λ[[l]... ]␈↓ ∧8␈↓ ¬λl␈↓ ¬8| ( )␈↓ π(␈↓ πxl␈↓ λ(| (A B C D)
␈↓ ↓H␈↓α␈↓ ↓Hmapfirst␈↓ αH| λ[[fn;l][null[l]...]]␈↓ ∧8␈↓ ¬λ␈↓ ¬8␈↓ π(␈↓ πxfn␈↓ λ(| λ[[x] concat[x;l]]␈↓
␈↓ ↓H␈↓␈↓αnull[l]␈↓␈αis␈αfalse␈αsince␈α␈↓αl␈↓␈αis␈α␈↓α(A␈αB␈αC␈αD)␈↓,␈αso␈αwe␈αevaluate␈α␈↓αconcat[fn[first[l]] ... ]␈↓.␈αThis␈α
involves␈αevaluating
␈↓ ↓H␈↓␈↓αfirst[l]␈↓␈α
in␈α
E␈↓β2␈↓,␈α
giving␈α
␈↓αA␈↓.␈α
We␈α
evaluate␈α
␈↓αfn␈↓␈α
in␈α
E␈↓β2␈↓␈α
and,␈α
finding␈α
a␈α
representation␈α
of␈α
a␈α
λ-definition,␈α
we
␈↓ ↓H␈↓make a new environment E␈↓β3␈↓ in which to evaluate the body of ␈↓αfn␈↓.
␈↓ ↓H␈↓As we make E␈↓β3␈↓, we add an entry binding ␈↓αx␈↓ to ␈↓αA␈↓ and we settle down in E␈↓β3␈↓ to evaluate ␈↓αconcat[x;l]␈↓:
␈↓ ↓H␈↓␈↓ ∧H ␈↓αconcat[x;l]␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬_E␈↓β3␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬_| E␈↓β2␈↓
␈↓ ↓H␈↓␈↓ ∧H__________
␈↓ ↓H␈↓␈↓ ∧H ␈↓α x␈↓ ¬_| A
␈↓ ↓H␈↓Since␈α␈↓αl␈↓␈αis␈αnon-local␈αto␈αE␈↓β3␈↓,␈αwe␈αfollow␈αthe␈αaccess␈αchain␈αto␈αfind␈αits␈αvalue␈αin␈αE␈↓β2␈↓␈αto␈αbe␈α␈↓α(A␈αB␈αC␈αD)␈↓.␈αBut
␈↓ ↓H␈↓that's not the expected value! We expected to find ␈↓α( )␈↓, which was hidden away in E␈↓β1␈↓.
␈↓ ↓H␈↓The␈α
trouble␈α
here␈αis␈α
that␈α
␈↓αl␈↓␈αwas␈α
rebound␈α
in␈αthe␈α
interim.␈α
The␈α
first␈αthing␈α
to␈α
note␈αis␈α
that␈α
the␈αproblem␈α
is
␈↓ ↓H␈↓caused␈α
by␈α
free␈α
variables␈α
and␈α
dynamic␈α
binding:␈α
␈↓αl␈↓␈α
is␈α
free␈α
in␈α
the␈α
functional␈α
argument.␈α Local␈α
variables
␈↓ ↓H␈↓aren't␈α
problematic;␈α∞neither␈α
are␈α∞global␈α
variables.␈α
The␈α∞desired␈α
binding␈α∞for␈α
␈↓αl␈↓␈α
is␈α∞the␈α
one␈α∞which␈α
was
␈↓ ↓H␈↓current␈α
when␈α
we␈α∞were␈α
binding␈α
the␈α∞functional␈α
argument␈α
to␈α
the␈α∞formal␈α
parameter␈α
␈↓αfn␈↓.␈α∞ A␈α
plausible
␈↓ ↓H␈↓solution␈α∞then␈α∞is␈α∂to␈α∞replace␈α∞all␈α∂non-local␈α∞variables␈α∞with␈α∂their␈α∞values␈α∞at␈α∂the␈α∞time␈α∞we␈α∂recognize␈α∞the
␈↓ ↓H␈↓functional␈α∂argument.␈α∞This␈α∂will␈α∞not␈α∂always␈α∞suffice.␈α∂ See␈α∞page 131␈α∂for␈α∞a␈α∂counterexample.␈α∂ A␈α∞more
␈↓ ↓H␈↓promising␈α
solution␈αis␈α
to␈αassociate␈α
the␈αname␈α
of␈αthe␈α
current␈αenvironment␈α
with␈αthe␈α
function␈α
and␈αuse
␈↓ ↓H␈↓that␈αpair␈αas␈αthe␈αvalue␈αto␈αbe␈αgiven␈αto␈αthe␈αformal␈αparameter.␈αWhen␈αwe␈αwant␈αto␈αapply␈αthe␈αfunctional
␈↓ ↓H␈↓argument␈α∞we␈α∞set␈α∞up␈α∞a␈α∞new␈α∞environment,␈α
introducing␈α∞a␈α∞local␈α∞table␈α∞with␈α∞the␈α∞λ-variables␈α∞bound␈α
to
␈↓ ↓H␈↓their␈α
values;␈α
only␈α∞␈↓↓now␈↓␈α
we␈α
use␈α
the␈α∞saved␈α
environment␈α
as␈α
the␈α∞beginning␈α
of␈α
the␈α
access␈α∞chain.␈α
The
␈↓ ↓H␈↓values␈α∂of␈α∂any␈α∂non-local␈α∂variables␈α∂which␈α∂we␈α∞encounter␈α∂in␈α∂the␈α∂process␈α∂of␈α∂applying␈α∂the␈α∞functional
␈↓ ↓H␈↓argument will be searched for in the saved environment.
␈↓ ↓H␈↓To␈α⊃initialize␈α⊃this␈α⊃process␈α⊃we␈α⊃require␈α⊃the␈α⊃recognition␈α⊃of␈α⊃instances␈α⊃of␈α⊃functional␈α⊃arguments.␈α⊂We
␈↓ ↓H␈↓introduce␈αa␈α
new␈αoperator␈α
called␈α␈↓αfunction␈↓.␈αThis␈α
operator␈αtakes␈α
one␈αargument:␈α
a␈αrepresentation␈αof␈α
the
␈↓ ↓H␈↓function.␈α∞The␈α∞effect␈α∞of␈α∞␈↓αfunction␈↓␈α∞will␈α∞be␈α∞to␈α∞construct␈α∞a␈α∞value␈α∞representing␈α∞that␈α∞argument␈α∞and␈α∞the
␈↓ ↓H␈↓environment which was current when the ␈↓αfunction␈↓-instance was evaluated.
␈↓ ↓H␈↓In␈αthe␈αcurrent␈α
example,␈αwe␈αwould␈αrecognize␈α
the␈α␈↓αfunction␈↓-construct␈αwhile␈αevaluating␈α
the␈αarguments
␈↓ ↓H␈↓to␈α␈↓αmapfirst␈↓;␈αthe␈α
environment␈αwhich␈αwas␈α
current␈αthen␈αwas␈αE␈↓β1␈↓.␈α
Therefore␈αas␈αwe␈α
build␈αE␈↓β2␈↓␈αwe␈αwant␈α
to
␈↓ ↓H␈↓associate␈α
the␈α
pair␈α
␈↓αλ[[x] concat[x;l]] - ␈↓E␈↓β1␈↓␈α∞with␈α
the␈α
formal␈α
parameter␈α∞␈↓αfn␈↓.␈α
Whenever␈α
we␈α
apply␈α∞␈↓αfn␈↓␈α
we
␈↓ ↓H␈↓␈↓↓3.10␈↓ ε⊂Functional Arguments and Functional Values 127␈↓
␈↓ ↓H␈↓want␈αto␈αuse␈α␈↓αλ[[x] concat[x;l]]␈↓;␈αand␈αwithin␈αthat␈αcontext,␈αwhenever␈αwe␈αwant␈α␈↓αl␈↓,␈αwe␈αwant␈αthe␈αvalue␈αof␈α␈↓αl␈↓
␈↓ ↓H␈↓in E␈↓β1␈↓.
␈↓ ↓H␈↓The␈α
function-environment␈α
pair␈α
is␈α∞called␈α
a␈α
␈↓↓closure␈↓␈α
or␈α
␈↓↓funarg␈↓.␈α∞ In␈α
our␈α
diagrams␈α
we␈α∞will␈α
designate
␈↓ ↓H␈↓the pair as:
␈↓ ↓H␈↓␈↓ ¬#<function>:<environment>.
␈↓ ↓H␈↓Therefore, in our example we should designate the value of the functional argument as:
␈↓ ↓H␈↓␈↓ ¬P␈↓αλ[[x] concat[x;l]]␈↓:E␈↓β1␈↓.
␈↓ ↓H␈↓We␈αmust␈αalso␈αextend␈αthe␈αmanipulation␈αof␈αWeizenbaum␈αenvironments␈αto␈αhandle␈αsuch␈αconstructions.
␈↓ ↓H␈↓The␈α⊂process␈α∂which␈α⊂recognizes␈α∂λ-definitions␈α⊂and␈α∂sets␈α⊂up␈α∂new␈α⊂environments␈α∂must␈α⊂now␈α⊂watch␈α∂for
␈↓ ↓H␈↓funargs.␈α
When␈α
it␈α
sees␈α
one␈αit␈α
uses␈α
the␈α
associated␈α
environment␈αas␈α
the␈α
access␈α
environment.␈α
Let's␈αdo
␈↓ ↓H␈↓the example again.
␈↓ ↓H␈↓␈↓ αλ ␈↓αfoo[( )]␈↓ βλ mapfirst[function[λ[[x] concat[x;l]]; ..]␈↓ πh [null[l] ... ]
␈↓ ↓H␈↓α␈↓ αλ␈↓ βλE␈↓β0␈↓α␈↓ ∧x␈↓ ¬H␈↓ ¬xE␈↓β1␈↓α␈↓ πh␈↓ λ8␈↓ λhE␈↓β2␈↓α
␈↓ ↓H␈↓α␈↓ αλ␈↓ βλ| /␈↓ ∧x␈↓ ¬H␈↓ ¬x| E␈↓β0␈↓α␈↓ πh␈↓ λ8␈↓ λh| E␈↓β1␈↓α
␈↓ ↓H␈↓α␈↓ αλ______________␈↓ ∧x=>␈↓ ¬H______␈↓ πh=>␈↓ λ8______ => . . .
␈↓ ↓H␈↓α␈↓ αλ foo␈↓ βλ| λ[[l]...␈↓ ∧x␈↓ ¬Hl␈↓ ¬x| ( )␈↓ πh␈↓ λ8l␈↓ λh| (A B C D)
␈↓ ↓H␈↓α␈↓ αλmapfirst␈↓ βλ| λ[[fn;l][null[l]...]]␈↓ ∧x␈↓ ¬H␈↓ ¬x␈↓ πh␈↓ λ8fn␈↓ λh| λ[[x] concat[x;l]]␈↓:E␈↓β1␈↓
␈↓ ↓H␈↓Things␈αare␈αas␈αbefore␈αexcept␈αnow␈α␈↓αfn␈↓␈αis␈αbound␈αto␈αthe␈αfunarg␈αpair␈αin␈αE␈↓β2␈↓.␈α We␈αlook␈αup␈α␈↓αfn␈↓␈αin␈αE␈↓β2␈↓␈αand,
␈↓ ↓H␈↓finding␈αa␈αλ-definition,␈αwe␈αmake␈αa␈αnew␈αenvironment␈αE␈↓β3␈↓␈αin␈αwhich␈αto␈αevaluate␈αthe␈αbody␈αof␈α␈↓αfn␈↓.␈αAs␈α
we
␈↓ ↓H␈↓make␈αE␈↓β3␈↓,␈αwe␈αadd␈α
an␈αentry␈αbinding␈α␈↓αx␈↓␈α
to␈α␈↓αA␈↓.␈α But␈αnow␈α
since␈αthe␈αλ-definition␈αis␈α
a␈αfunarg␈αwe␈αmake␈α
the
␈↓ ↓H␈↓access environment E␈↓β1␈↓ as saved with ␈↓αfn␈↓. Thus we settle down in E␈↓β3␈↓ to evaluate ␈↓αconcat[x;l]␈↓:
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬_␈↓αconcat[x;l]␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬_E␈↓β3␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬_| E␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ∧H__________
␈↓ ↓H␈↓␈↓ ∧H ␈↓α x␈↓ ¬_| A
␈↓ ↓H␈↓Since␈α
␈↓αl␈↓␈α
is␈α
non-local␈α
to␈α∞E␈↓β3␈↓,␈α
we␈α
follow␈α
the␈α
access␈α∞chain␈α
to␈α
find␈α
its␈α
value␈α∞in␈α
E␈↓β1␈↓␈α
to␈α
be␈α
␈↓α( )␈↓␈α∞as␈α
desired.
␈↓ ↓H␈↓Thus instead of simply tracing back to the previous environment we detour around E␈↓β2␈↓:
␈↓ ↓H␈↓␈↓↓128 Evaluation␈↓ )3.10␈↓
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_␈↓E␈↓β0␈↓∂
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_↑
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_~
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_␈↓E␈↓β1␈↓∂←␈↓ ¬H⊃
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_↑␈↓ ¬H.
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_~␈↓ ¬H.
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_␈↓E␈↓β2␈↓∂␈↓ ¬H↑
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_↑␈↓ ¬H.
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_~␈↓ ¬H.
␈↓"␈↓ ↓H␈↓∂␈↓ ¬_␈↓E␈↓β3␈↓∂→␈↓ ¬H$
␈↓ ↓H␈↓However,␈α∩there␈α∪is␈α∩still␈α∪some␈α∩information␈α∪which␈α∩we␈α∪must␈α∩make␈α∪explicit␈α∩if␈α∪these␈α∩Weizenbaum
␈↓ ↓H␈↓diagrams␈αare␈αto␈αfaithfully␈αrepresent␈αthe␈αprocess␈αof␈αevaluation.␈α Namely,␈αafter␈αwe␈αhave␈αfinished␈αthe
␈↓ ↓H␈↓evaluation␈αof␈α␈↓αconcat[x;l]␈↓␈αwe␈αare␈αto␈αrestore␈αa␈αprevious␈αenvironment.␈αWhich␈αone␈αis␈αit?␈α It␈αisn't␈αE␈↓β1␈↓,␈αit's
␈↓ ↓H␈↓E␈↓β2␈↓! That information is not available in our diagram, so we must correct the situation.
␈↓ ↓H␈↓In␈α
the␈α
left-hand␈α
quadrant␈α
of␈α
our␈α
diagram␈α
we␈α
place␈α
the␈α
name␈α
of␈α
the␈α
environment␈α
which␈α
we␈αwish
␈↓ ↓H␈↓restored␈α
when␈α
we␈αleave␈α
the␈α
current␈αenvironment.␈α
That␈α
environment␈α
name␈αwill␈α
be␈α
called␈αthe␈α
␈↓↓control
␈↓ ↓H␈↓↓environment␈↓,␈α⊂and␈α⊂will␈α⊃head␈α⊂a␈α⊂chain␈α⊃of␈α⊂environments,␈α⊂called␈α⊂the␈α⊃control␈α⊂chain␈α⊂␈↓π 81␈↓.␈α⊃ Here's␈α⊂the
␈↓ ↓H␈↓correct picture:
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬_␈↓αconcat[x;l]␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬_E␈↓β3␈↓
␈↓ ↓H␈↓␈↓ ∧HE␈↓β2␈↓␈↓ ¬_| E␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ∧H__________
␈↓ ↓H␈↓␈↓ ∧H ␈↓α x␈↓ ¬_| A
␈↓ ↓H␈↓So␈α⊃after␈α⊃we␈α⊂have␈α⊃finished␈α⊃the␈α⊂computation␈α⊃in␈α⊃E␈↓β3␈↓␈α⊂we␈α⊃return␈α⊃control␈α⊂to␈α⊃E␈↓β2␈↓.␈α⊃ Thus␈α⊃the␈α⊂general
␈↓ ↓H␈↓structure of an environment is as follows:
␈↓ ↓H␈↓␈↓ ¬H␈↓ εX␈↓ Form␈↓
␈↓ ↓H␈↓␈↓ ¬H␈↓ εXE␈↓βcurrent␈↓
␈↓ ↓H␈↓␈↓ ¬HE␈↓βcontrol␈↓␈↓ εX| E␈↓βaccess␈↓
␈↓ ↓H␈↓␈↓ ¬H_________________________
␈↓ ↓H␈↓␈↓ ¬Hvar␈↓ εX| value
␈↓ ↓H␈↓␈↓ ¬H␈↓αx␈↓β1␈↓␈↓ εX| . . .
␈↓ ↓H␈↓␈↓ ¬H␈↓αx␈↓β2␈↓␈↓ εX| . . .
␈↓ ↓H␈↓␈↓ ¬H. . .␈↓ εX| . . .
␈↓ ↓H␈↓␈↓ ¬H␈↓αx␈↓βn␈↓␈↓ εX| . . .
␈↓ ↓H␈↓␈↓ ¬H␈↓ εX|
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 81␈↓␈αIn␈αAlgol,␈αthe␈αaccess␈αchain␈αis␈αcalled␈αthe␈αstatic␈αchain,␈αand␈αthe␈αcontrol␈αchain␈αis␈αcalled␈αthe␈αdynamic
␈↓ ↓H␈↓chain.
␈↓ ↓H␈↓␈↓↓3.10␈↓ ε⊂Functional Arguments and Functional Values 129␈↓
␈↓ ↓H␈↓Here's␈α
another␈α
example,␈α
involving␈α
a␈α
function␈α
to␈α
produce␈α
the␈α
composition␈α
of␈α
two␈α
unary␈αfunctions.
␈↓ ↓H␈↓We␈α
will␈α
call␈α∞the␈α
function␈α
␈↓αcompose␈↓.␈α
The␈α∞value␈α
returned␈α
by␈α
␈↓αcompose␈↓␈α∞will␈α
be␈α
a␈α
function;␈α∞that␈α
means
␈↓ ↓H␈↓␈↓αcompose␈↓ will produce a functional value:
␈↓ ↓H␈↓α␈↓ ∧>compose[function[car];function[cdr]] = cadr
␈↓ ↓H␈↓α␈↓with a plausible definition as:␈↓α
␈↓ ↓H␈↓α␈↓ ¬βcompose <= λ[[f;g] λ[[x]f[g[x]]]]
␈↓ ↓H␈↓This␈α∂definition␈α∂of␈α∂␈↓αcompose␈↓␈α∂is␈α∞almost␈α∂right.␈α∂ The␈α∂value␈α∂returned␈α∞by␈α∂␈↓αcompose␈↓␈α∂is␈α∂to␈α∂be␈α∂a␈α∞function.
␈↓ ↓H␈↓Indeed␈α∂it␈α∂is␈α∂an␈α∞instance␈α∂of␈α∂a␈α∂␈↓↓functional␈α∞value␈↓,␈α∂so,␈α∂as␈α∂with␈α∞functional␈α∂arguments,␈α∂it␈α∂needs␈α∂to␈α∞be
␈↓ ↓H␈↓decorated␈αwith␈α
␈↓αfunction␈↓␈αso␈αthat␈α
the␈αenvironment␈α
which␈αcontains␈αthe␈α
right␈αbindings␈αfor␈α
␈↓αf␈↓␈αand␈α
␈↓αg␈↓␈αis
␈↓ ↓H␈↓saved.␈αThat␈αenvironment␈αis␈αthe␈αone␈α
which␈αwas␈αcurrent␈αwhen␈αthe␈α␈↓αfunction␈↓-construct␈αwas␈α
recognized.
␈↓ ↓H␈↓So we write:
␈↓ ↓H␈↓␈↓ εP␈↓ ∧=␈↓αcompose <= λ[[f;g] function[λ[[x] f[g[x]]]]].
␈↓ ↓H␈↓α␈↓ β*␈↓Now try: ␈↓αapp[cons[A;(B . C)];compose[function[car];function[cdr]]]␈↓
␈↓ ↓H␈↓␈↓ ¬%where: ␈↓αapp <= λ[[y;f] f[y]]␈↓
␈↓ ↓H␈↓As␈αusual␈αwe␈α
evaluate␈αthe␈αarguments␈α
to␈α␈↓αapp␈↓,␈αbind␈α
the␈αresults␈αto␈α
␈↓αy␈↓␈αand␈α␈↓αf␈↓␈α
and␈αevaluate␈αthe␈α
body␈αof
␈↓ ↓H␈↓␈↓αapp␈↓.
␈↓ ↓H␈↓␈↓ β(␈↓αapp[cons[A;(B . C)];function[compose[function[car];function[cdr]]]]␈↓
␈↓ ↓H␈↓␈↓ β(␈↓ ∧(E␈↓β0␈↓
␈↓ ↓H␈↓␈↓ β(␈↓ ∧(/| /
␈↓ ↓H␈↓␈↓ β(______________
␈↓ ↓H␈↓␈↓ β( ␈↓αapp␈↓ ∧( | λ[[y;f] f[y]]
␈↓ ↓H␈↓α␈↓ β(compose␈↓ ∧( | λ[[f;g] function[λ[[x] f[g[x]]]]]␈↓
␈↓ ↓H␈↓Evaluation␈α∪of␈α∩the␈α∪first␈α∩argument␈α∪to␈α∪␈↓αapp␈↓␈α∩brings␈α∪no␈α∩surprises;␈α∪we␈α∩get␈α∪␈↓α(A . (B . C))␈↓.␈α∪We␈α∩begin
␈↓ ↓H␈↓evaluating␈αthe␈αsecond␈αargument;␈αwe␈αfind␈αthe␈αdefinition␈αof␈α␈↓αcompose␈↓␈αin␈αthe␈αenvironment␈αand␈αsince␈αit
␈↓ ↓H␈↓is a λ-definition we set up a new environment, E␈↓β1␈↓, and evaluate the body ␈↓αfunction[λ[[x] f[g[x]]]]␈↓:
␈↓ ↓H␈↓␈↓ ∧H␈↓αfunction[λ[[x] f[g[x]]]]␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬HE␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ∧H E␈↓β0␈↓␈↓ ¬H| E␈↓β0␈↓
␈↓ ↓H␈↓␈↓ ∧H __________
␈↓ ↓H␈↓␈↓ ∧H ␈↓αf␈↓ ¬H| car␈↓:E␈↓β0␈↓α
␈↓ ↓H␈↓α␈↓ ∧H g␈↓ ¬H| cdr␈↓:E␈↓β0␈↓
␈↓ ↓H␈↓Again,␈α_the␈α↔recognition␈α_of␈α↔the␈α_␈↓αfunction␈↓-construct␈α↔says␈α_return␈α↔a␈α_funarg-pair␈α↔as␈α_value.␈α↔The
␈↓ ↓H␈↓environment␈α
we␈α
associate␈α
is␈α
the␈α
current␈α
one,␈α
E␈↓β1␈↓.␈α∞We␈α
now␈α
go␈α
back␈α
to␈α
E␈↓β0␈↓,␈α
using␈α
the␈α∞control␈α
chain.
␈↓ ↓H␈↓Since␈α
both␈αarguments␈α
to␈α␈↓αapp␈↓␈α
are␈αnow␈α
evaluated,␈αwe␈α
find␈αthe␈α
definition␈αof␈α
␈↓αapp␈↓␈αand␈α
set␈αup␈α
a␈αnew
␈↓ ↓H␈↓environment E␈↓β2␈↓. Thus:
␈↓ ↓H␈↓␈↓↓130 Evaluation␈↓ )3.10␈↓
␈↓ ↓H␈↓␈↓ β(␈↓ ∧(␈↓αf[y]␈↓ ε_␈↓ εh␈↓ π_f[g[x]]␈↓
␈↓ ↓H␈↓␈↓ β(␈↓ ∧(E␈↓β2␈↓␈↓ ε_␈↓ εh␈↓ π_E␈↓β3␈↓
␈↓ ↓H␈↓␈↓ β( E␈↓β0␈↓␈↓ ∧(| E␈↓β0␈↓␈↓ ε_␈↓ εh E␈↓β2␈↓␈↓ π_| E␈↓β1␈↓
␈↓ ↓H␈↓␈↓ β( __________␈↓ ε_=>␈↓ εh_________
␈↓ ↓H␈↓␈↓ β( ␈↓αy␈↓ ∧(| (A . (B . C))␈↓ ε_␈↓ εhx␈↓ π_| (A . (B . C))
␈↓ ↓H␈↓α␈↓ β( f␈↓ ∧(| λ[[x] f[g[x]]]␈↓:E␈↓β1␈↓
␈↓ ↓H␈↓The␈αform␈αto␈αbe␈αevaluated␈αin␈αE␈↓β2␈↓␈αis␈α␈↓αf[y]␈↓;␈αwe␈αfind␈α␈↓αy␈↓␈αand␈α␈↓αf␈↓␈αboth␈αlocally.␈αWe␈αevaluate␈αthe␈αargument␈α␈↓αy␈↓,
␈↓ ↓H␈↓then␈αsince␈α
␈↓αf␈↓␈αis␈αa␈α
λ-definition,␈αwe␈αset␈α
up␈αa␈αnew␈α
environment␈αbinding␈αthe␈α
λ-variable␈α␈↓αx␈↓␈αto␈α
the␈αvalue
␈↓ ↓H␈↓␈↓α(A . (B . C))␈↓.␈αBut␈αthe␈αλ-definition␈αis␈αalso␈αa␈αfunarg;␈αtherefore␈αthe␈αaccess␈αenvironment␈αstored␈αin␈αE␈↓β3␈↓␈αis
␈↓ ↓H␈↓E␈↓β1␈↓.␈α The␈αcontrol␈αcomponent␈αof␈αE␈↓β3␈↓␈αis␈αset␈αto␈αthe␈αprior␈αenvironment,␈αE␈↓β2␈↓;␈αand␈αwe␈αbegin␈αevaluation␈αof
␈↓ ↓H␈↓the body ␈↓αf[g[x]]␈↓.
␈↓ ↓H␈↓Now␈αin␈αE␈↓β3␈↓␈αwe␈αfind␈α␈↓αx␈↓␈αlocally␈αbut␈αhave␈αto␈αresort␈αto␈αthe␈αaccess␈αchain␈αto␈αfind␈α␈↓αf␈↓␈αand␈α␈↓αg␈↓;␈αusing␈αfunargs,
␈↓ ↓H␈↓we have set up the appropriate environments. From E␈↓β3␈↓ we have access to E␈↓β1␈↓␈↓π 82␈↓:
␈↓"␈↓ ↓H␈↓∂ ␈↓E␈↓β0␈↓∂
␈↓"␈↓ ↓H␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ ␈↓E␈↓β1␈↓∂ ␈↓E␈↓β2␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ \
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ \
␈↓"␈↓ ↓H␈↓∂ -→␈↓E␈↓β3␈↓∂
␈↓ ↓H␈↓The␈αrest␈αof␈αthe␈αevaluation␈αgoes␈αwithout␈αincident:␈α
we␈αfinish␈αthe␈αevaluation␈αin␈αE␈↓β3␈↓␈αand␈αreturn␈α
to␈αE␈↓β2␈↓
␈↓ ↓H␈↓and finally to E␈↓β0␈↓ following the control evironments.
␈↓ ↓H␈↓Notice␈αthat␈α␈↓αf␈↓␈αand␈α␈↓αg␈↓␈αin␈αthe␈αbody␈αof␈α␈↓αcompose␈↓␈αare␈αfree␈αvariables␈αand␈αtherefore␈αtheir␈αbindings␈αare␈αnot
␈↓ ↓H␈↓to␈αbe␈α
found␈αin␈α
the␈αlocal␈α
environment.␈α Since␈αthe␈α
interesting␈αapplications␈α
of␈αsuch␈α
functions␈αusually
␈↓ ↓H␈↓involve␈α⊂free␈α⊂variables,␈α⊂we␈α⊂must␈α⊂deal␈α⊃with␈α⊂them.␈α⊂ In␈α⊂particular,␈α⊂the␈α⊂␈↓αlabel␈↓␈α⊂operator␈α⊃will␈α⊂typically
␈↓ ↓H␈↓involve free variables. We remarked that ␈↓αf␈↓ in:
␈↓ ↓H␈↓␈↓ ∧O␈↓αf <= λ[[x][zerop[x] → 1; ␈↓
t␈↓α → *[x;f[x-1]]] ]␈↓
␈↓ ↓H␈↓is␈αfree.␈α
But␈αwe␈α
want␈αthe␈α
occurrence␈αof␈α
␈↓αf␈↓␈αon␈αthe␈α
right␈αto␈α
be␈αsynonymous␈α
with␈αthe␈α
␈↓αf␈↓␈αbeing␈αdefined␈α
on
␈↓ ↓H␈↓the␈α
left.␈α
We␈α
can␈αdo␈α
this␈α
by␈α
"tying␈αa␈α
knot"␈α
in␈α
the␈αaccess␈α
environment␈α
chain.␈α
Therefore,␈α
we␈αshould
␈↓ ↓H␈↓modify the diagram for ␈↓αlabel␈↓ to be:
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 82␈↓ and from there to E␈↓β0␈↓ if it were needed.
␈↓ ↓H␈↓␈↓↓3.10␈↓ ε⊂Functional Arguments and Functional Values 131␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓αlabel[f;λ[[x] ␈↓λx␈↓α[x]]][A]␈↓␈↓ ∧x␈↓ ¬H␈↓λx␈↓α[x]␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓ βλE␈↓β0␈↓␈↓ ∧x␈↓ ¬H␈↓ ¬xE␈↓β1␈↓
␈↓ ↓H␈↓␈↓ αλ␈↓ βλ | /␈↓ ∧x␈↓ ¬H␈↓ ¬x| E␈↓β0␈↓
␈↓ ↓H␈↓␈↓ αλ ________␈↓ ∧x=> ...␈↓ ¬H______
␈↓ ↓H␈↓␈↓ αλ␈↓ βλ |␈↓ ∧x␈↓ ¬H␈↓αf␈↓ ¬x| λ[[x] ␈↓λx␈↓α[x]]␈↓:E␈↓β1␈↓α
␈↓ ↓H␈↓α␈↓ αλ␈↓ βλ␈↓ ∧x␈↓ ¬Hx␈↓ ¬x| A
␈↓ ↓H␈↓Notice␈α∩that␈α⊃the␈α∩effect␈α⊃of␈α∩␈↓αlabel␈↓␈α⊃is␈α∩to␈α⊃build␈α∩␈↓αfunction[λ[[x]␈α⊃␈↓λx␈↓α]]␈↓␈α∩and␈α⊃associate␈α∩that␈α⊃with␈α∩␈↓αf␈↓.␈α∩ If␈α⊃we
␈↓ ↓H␈↓attempted␈α⊃to␈α⊃implement␈α⊃␈↓αfunction[␈↓λf␈↓α]␈↓␈α⊃by␈α⊃replacing␈α⊃all␈α⊃non-local␈α⊃variables␈α⊃in␈α⊃␈↓λf␈↓␈α⊃by␈α⊃their␈α⊂current
␈↓ ↓H␈↓values we wouldn't always get what we expect.
␈↓ ↓H␈↓Consider ␈↓ ∧B␈↓α fact <= λ[[x][x=0 → 1; ␈↓
t␈↓α → *[x;fact[x-1]]]]␈↓:
␈↓ ↓H␈↓If the current environment is E␈↓βi␈↓:
␈↓ ↓H␈↓␈↓ ¬_␈↓ ¬XE␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_E␈↓βc␈↓␈↓ ¬X|␈↓ ε_E␈↓βa␈↓
␈↓ ↓H␈↓␈↓ ¬____________
␈↓ ↓H␈↓␈↓ ¬_␈↓αfact␈↓␈↓ ¬X| ␈↓αfoo␈↓
␈↓ ↓H␈↓then executing ␈↓αfact <= ... ␈↓ should give something like:
␈↓ ↓H␈↓␈↓ ¬_␈↓ ¬XE␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_E␈↓βc␈↓␈↓ ¬X|␈↓ ε_E␈↓βa␈↓
␈↓ ↓H␈↓␈↓ ¬____________
␈↓ ↓H␈↓␈↓ ¬_␈↓αfact␈↓␈↓ ¬X| ␈↓αλ[[x] ...fact[x-1]]␈↓ :E␈↓βi␈↓
␈↓ ↓H␈↓rather than:
␈↓ ↓H␈↓␈↓ ¬_␈↓ ¬XE␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_E␈↓βc␈↓␈↓ ¬X|␈↓ ε_E␈↓βa␈↓
␈↓ ↓H␈↓␈↓ ¬____________
␈↓ ↓H␈↓␈↓ ¬_␈↓αfact␈↓␈↓ ¬X| ␈↓αλ[[x] ...foo[x-1]]
␈↓ ↓H␈↓Since␈α
every␈α
language␈α
construct␈α∞in␈α
LISP␈α
must␈α
have␈α
an␈α∞S-expr␈α
representation␈α
we␈α
must␈α∞include␈α
the
␈↓ ↓H␈↓␈↓αfunction␈↓-construct. Its translation scheme is simple: represent ␈↓αfunction[␈↓λx␈↓α]␈↓ as ␈↓α(FUNCTION ␈↓
R␈↓∞(␈↓λx␈↓∞)␈↓α)␈↓.
␈↓ ↓H␈↓Thus:
␈↓ ↓H␈↓␈↓ ∧>␈↓αfunction[λ[[x] f[g[x]]] ␈↓ has an ␈↓
R␈↓-image of,
␈↓ ↓H␈↓␈↓ ∧9␈↓α(FUNCTION (LAMBDA (X) (F (G X)))).␈↓
␈↓ ↓H␈↓We␈α∞must␈α∞also␈α∞develop␈α∞new␈α∞sections␈α∞of␈α∞␈↓αeval␈↓␈α∞to␈α∞deal␈α∞with␈α∞␈↓αFUNCTION␈↓.␈α∞The␈α∞device␈α∞LISP␈α∞used␈α
to
␈↓ ↓H␈↓associate␈α∩environments␈α∪with␈α∩functions␈α∪is␈α∩called␈α∩the␈α∪␈↓αFUNARG␈↓␈α∩device␈↓π 83␈↓.␈α∪ When␈α∩␈↓αeval␈↓␈α∪sees␈α∩the
␈↓ ↓H␈↓construction ␈↓α(FUNCTION ␈↓fn␈↓α)␈↓ it returns as value the list:
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 83␈↓ More is said about implementations of ␈↓αFUNARG␈↓ in Section 6.18.
␈↓ ↓H␈↓␈↓↓132 Evaluation␈↓ )3.10␈↓
␈↓ ↓H␈↓␈↓ ↓z␈↓α(FUNARG ␈↓fn "saved"␈↓α)␈↓. Where "saved" represents a pointer to the current symbol table.
␈↓ ↓H␈↓It␈α∞is␈α
␈↓αapply␈↓␈α∞that␈α
recognizes␈α∞␈↓α(FUNARG␈α
␈↓fn␈α∞"saved"␈↓α)␈↓.␈α
When␈α∞we␈α
are␈α∞␈↓↓calling␈↓α␈α
fn␈↓,␈α∞we␈α
use␈α∞the␈α
"saved"
␈↓ ↓H␈↓symbol table for accessing non-local variables.
␈↓ ↓H␈↓Thus␈α
there␈α
are␈α␈↓↓two␈↓␈α
environments␈α
involved␈αin␈α
the␈α
proper␈αhandling␈α
of␈α
functional␈α
arguments.␈αFirst
␈↓ ↓H␈↓there␈α∃is␈α∀the␈α∃environment␈α∃which␈α∀is␈α∃saved␈α∃with␈α∀the␈α∃␈↓αFUNARG␈↓.␈α∃ This␈α∀is␈α∃called␈α∃the␈α∀␈↓↓binding
␈↓ ↓H␈↓↓environment␈↓␈α∃since␈α∃it␈α∃is␈α∃the␈α∃environment␈α∃current␈α∃at␈α∃the␈α∃time␈α∃the␈α∃functional␈α∃argument␈α∃was
␈↓ ↓H␈↓constructed␈α⊗or␈α⊗bound.␈α↔The␈α⊗second␈α⊗environment,␈α⊗called␈α↔the␈α⊗␈↓↓activation␈α⊗environment␈↓,␈α↔is␈α⊗the
␈↓ ↓H␈↓environment␈α⊂which␈α⊂is␈α⊂current␈α∂when␈α⊂the␈α⊂functional␈α⊂argument␈α∂is␈α⊂␈↓↓applied␈↓␈α⊂or␈α⊂activated.␈α⊂Thus␈α∂the
␈↓ ↓H␈↓activation␈αenvironment␈αis␈α
used␈αto␈αlocate␈αlocal␈α
variables,␈αbut␈αif␈αa␈α
non-local␈αvariable␈αis␈α
needed␈αthen
␈↓ ↓H␈↓the binding environment is examined.
␈↓ ↓H␈↓It␈αis␈αthe␈αduty␈αof␈α␈↓αeval␈↓␈αand␈α␈↓αapply␈↓␈αto␈αuse␈αthe␈α␈↓αFUNARG␈↓␈αdevice␈αto␈αmaintain␈αthe␈αproper␈αcontrol␈αof␈αthe
␈↓ ↓H␈↓activation and binding environments.
␈↓ ↓H␈↓Finally,␈α∂we␈α∂should␈α⊂update␈α∂our␈α∂description␈α⊂of␈α∂the␈α∂usage␈α⊂of␈α∂Weizenbaum␈α∂environments␈α⊂given␈α∂on
␈↓ ↓H␈↓page 120:
␈↓ ↓H␈↓␈↓ α_When␈α
the␈α␈↓αfunction␈↓␈α
construct␈αis␈α
recognized,␈α
we␈αmanufacture␈α
a␈α␈↓αFUNARG␈↓␈α
triple␈α
consisting␈αof
␈↓ ↓H␈↓␈↓ α_the␈α⊃atom␈α⊃␈↓αFUNARG␈↓,␈α⊂the␈α⊃function␈α⊃described␈α⊂in␈α⊃the␈α⊃instance␈α⊂of␈α⊃␈↓αfunction␈↓,␈α⊃and␈α⊃the␈α⊂current
␈↓ ↓H␈↓␈↓ α_environment.␈α∞ This␈α∞triple␈α∞is␈α∞the␈α∞value␈α∞of␈α
the␈α∞␈↓αfunction␈↓␈α∞construct␈α∞and␈α∞may␈α∞be␈α∞bound␈α∞to␈α
any
␈↓ ↓H␈↓␈↓ α_LISP␈α∪variable;␈α∪typically␈α∪the␈α∪LISP␈α∪variable␈α∩will␈α∪appear␈α∪in␈α∪an␈α∪expression␈α∪in␈α∪a␈α∩position
␈↓ ↓H␈↓␈↓ α_reserved for functions.
␈↓ ↓H␈↓␈↓ α_When␈αdoing␈αa␈αλ-binding,␈αset␈αup␈αa␈αnew␈α
E␈↓βnew␈↓␈αwith␈αthe␈αλ-variables␈αas␈αthe␈αlocal␈αvariable␈α
entries
␈↓ ↓H␈↓␈↓ α_and␈αthe␈αvalues␈α
of␈αthe␈αarguments␈αas␈α
the␈αcorresponding␈αvalue␈αentries.␈α
The␈αcontrol␈αslot␈αof␈α
E␈↓βnew␈↓
␈↓ ↓H␈↓␈↓ α_always␈α∩points␈α∩to␈α∩the␈α⊃previous␈α∩symbol␈α∩table.␈α∩The␈α∩access␈α⊃slot␈α∩also␈α∩points␈α∩to␈α∩the␈α⊃previous
␈↓ ↓H␈↓␈↓ α_environment␈αunless␈αthe␈αfunction␈αbeing␈αapplied␈αis␈αa␈α␈↓αFUNARG␈↓.␈α If␈αit␈α␈↓↓is␈↓␈αa␈α␈↓αFUNARG␈↓,␈αthen␈αset
␈↓ ↓H␈↓␈↓ α_the access slot to the environment which was saved with the ␈↓αFUNARG␈↓.
␈↓ ↓H␈↓␈↓ α_The␈αevaluation␈αof␈αthe␈αbody␈αof␈αthe␈α
λ-expression␈αtakes␈αplace␈αusing␈αE␈↓βnew␈↓;␈αwhen␈αa␈αlocal␈α
variable
␈↓ ↓H␈↓␈↓ α_is␈αaccessed␈αwe␈αfind␈αit␈αin␈αE␈↓βnew␈↓;␈αwhen␈αa␈αnon-local␈αvariable␈αoccurs,␈αwe␈αchase␈αthe␈αaccess␈αchain␈αto
␈↓ ↓H␈↓␈↓ α_find␈α
its␈αvalue.␈α
When␈αthe␈α
evaluation␈α
of␈αthe␈α
body␈αis␈α
completed,␈αthe␈α
previous␈α
environment␈αis
␈↓ ↓H␈↓␈↓ α_restored. E␈↓βnew␈↓ disappears unless the value of the computation is a functional value.
␈↓ ↓H␈↓Notice␈αthat␈α
there␈αis␈α
a␈αcertain␈α
asymmetry␈αabout␈αaccess␈α
and␈αcontrol.␈α
The␈αcontrol␈α
slot␈αalways␈αpoints␈α
at
␈↓ ↓H␈↓the␈α
previous␈α
environment,␈α
while␈α
the␈α
access␈α
slot␈α
may␈αvary.␈α
It␈α
may␈α
follow␈α
control,␈α
as␈α
is␈α
the␈α
case␈αon
␈↓ ↓H␈↓simple␈αfunction␈αcalls;␈αit␈αmay␈αpoint␈αto␈αan␈αenvironment␈αfurther␈αdown␈αthe␈αcontrol␈αchain,␈αas␈αis␈αthe␈α
case
␈↓ ↓H␈↓for␈αfunctional␈αarguments;␈αit␈αmay␈αpoint␈αto␈αan␈αenvironment␈αwhich␈αcontrol␈αcannot␈αreturn␈αto,␈αas␈αis␈αthe
␈↓ ↓H␈↓case for functional values; or it may point to itself as is the case for ␈↓αlabel␈↓'s implementation.
␈↓ ↓H␈↓There␈α
is␈αanother␈α
asymmetry␈α
in␈αthe␈α
properties␈αof␈α
access␈α
and␈αcontrol.␈α
The␈αaccess␈α
environment␈α
is␈αa
␈↓ ↓H␈↓self-sufficient␈α∃data␈α∀structure;␈α∃it␈α∀can␈α∃be␈α∀described␈α∃and␈α∀manipulated␈α∃as␈α∀such␈α∃using␈α∃the␈α∀usual
␈↓ ↓H␈↓constructors,␈αselectors,␈αand␈α
recognizers.␈α Typically␈αsuch␈αenvironments␈α
come␈αinto␈αexistence␈αas␈α
a␈αpart
␈↓ ↓H␈↓␈↓↓3.10␈↓ ε⊂Functional Arguments and Functional Values 133␈↓
␈↓ ↓H␈↓of␈αa␈αcomputation;␈αthey␈α
are␈αconstructed␈αduring␈αthe␈αλ-binding␈α
process.␈α We␈αcan␈αimplicitly␈α
save␈αsuch
␈↓ ↓H␈↓an␈α⊂environment␈α⊂through␈α⊂the␈α⊂␈↓αFUNARG␈↓␈α⊂device;␈α⊂and␈α⊂we␈α⊂can␈α⊂explicitly␈α⊂build␈α⊂such␈α⊂environments
␈↓ ↓H␈↓using␈αthe␈αdata␈αstructure␈αoperations␈αand␈αpass␈αthem␈αto␈α␈↓αeval␈↓␈αas␈αa␈αsymbol␈αtable.␈αBut␈αsymbol␈αtables␈αare
␈↓ ↓H␈↓independent␈αof␈αthe␈αmethod␈αused␈αto␈αcreate␈αthem.␈αIn␈αparticular,␈αonce␈αa␈αtable␈αhas␈αbeen␈αcaptured␈αby␈αa
␈↓ ↓H␈↓␈↓αFUNARG␈↓␈α∂we␈α∂need␈α∂not␈α∞retain␈α∂any␈α∂information␈α∂about␈α∞the␈α∂computation␈α∂which␈α∂created␈α∂that␈α∞table.
␈↓ ↓H␈↓However␈αthe␈αidea␈αof␈α"control"␈αand␈α"state␈αof␈αcomputation"␈αis␈αintegrally␈αtied␈αto␈αaccess␈αstructure.␈α The
␈↓ ↓H␈↓state␈α∂of␈α∂the␈α∂computation␈α∂involves␈α∂the␈α⊂expression␈α∂currently␈α∂being␈α∂evaluated,␈α∂the␈α∂history␈α⊂of␈α∂those
␈↓ ↓H␈↓computations␈αwhich␈αare␈αsuspended␈αand␈αwaiting␈αfor␈αthe␈αcompletion␈αof␈αthe␈αcurrent␈αcomputation,␈α
and
␈↓ ↓H␈↓it␈α∪also␈α∪involves␈α∀the␈α∪access␈α∪environment␈α∀since␈α∪that␈α∪is␈α∪necessary␈α∀for␈α∪the␈α∪correct␈α∀evaluation␈α∪of
␈↓ ↓H␈↓variables.␈α To␈α"save␈αthe␈αstate␈αof␈αcomputation"␈αimplies␈αsaving␈αthe␈αpartial␈αcomputation␈αto␈αthat␈αpoint,
␈↓ ↓H␈↓saving the expression being evaluated, and saving the current access environment.
␈↓ ↓H␈↓To␈α
a␈α
large␈α
extent,␈α
"control␈α
environment"␈α
is␈α
a␈α
misnomer.␈α
What␈α
we␈α
are␈α
intending␈α
to␈α
capture␈α
is␈α
the
␈↓ ↓H␈↓idea␈αof␈αa␈αsuspended␈αcomputation:␈αsuspended␈αuntil␈αthe␈αsubsidiary␈αcomputation␈αhas␈αbeen␈αcompleted.
␈↓ ↓H␈↓Part␈α_of␈α→the␈α_suspended␈α_computation␈α→␈↓↓is␈↓␈α_the␈α_"control␈α→environment",␈α_but␈α_there's␈α→more.␈α_The
␈↓ ↓H␈↓Weizenbaum␈α∀diagrams␈α∃show␈α∀part␈α∀of␈α∃the␈α∀information;␈α∀they␈α∃show␈α∀the␈α∀environments␈α∃and␈α∀the
␈↓ ↓H␈↓expressions␈αbeing␈α
evaluated.␈αHowever␈αthey␈α
leave␈αimplicit␈αthe␈α
dynamics␈αof␈αthe␈α
computation:␈αwhich
␈↓ ↓H␈↓argument␈α⊂is␈α⊂being␈α∂evaluated,␈α⊂and␈α⊂where␈α∂the␈α⊂partial␈α⊂results␈α∂are␈α⊂being␈α⊂stored,␈α∂and␈α⊂where␈α⊂in␈α∂the
␈↓ ↓H␈↓expression␈α∂we␈α⊂are␈α∂to␈α∂continue␈α⊂when␈α∂the␈α⊂subsidiary␈α∂computation␈α∂is␈α⊂completed.␈α∂In␈α⊂Section 4.4␈α∂we
␈↓ ↓H␈↓will␈α∞develop␈α∞a␈α∞different␈α∞␈↓αeval␈↓␈α∞family␈α∞which␈α∞will␈α∞make␈α∞much␈α∞of␈α∞this␈α∞information␈α∞explicit.␈α∞ Also␈α
in
␈↓ ↓H␈↓Section 4.4␈α⊂we␈α∂will␈α⊂examine␈α∂the␈α⊂possibility␈α∂of␈α⊂expanding␈α∂the␈α⊂behavior␈α∂of␈α⊂control␈α∂slots.␈α⊂That␈α∂is,
␈↓ ↓H␈↓allowing environments other than the predecessor to appear in the control slot of an environment.
␈↓ ↓H␈↓We␈α
have␈α
already␈α
remarked␈α
that␈α
functions␈α
are␈α
parametric␈α
values;␈α
to␈α
that␈α
we␈α
must␈α
add␈αthat␈α
functions
␈↓ ↓H␈↓may␈αalso␈α
be␈αtied␈αto␈α
the␈αenvironment␈αin␈α
which␈αthey␈αwere␈α
created;␈αthey␈αcannot␈α
be␈αevaluated␈α␈↓αin␈α
vacuo␈↓.
␈↓ ↓H␈↓What␈αdoes␈αthis␈αsay␈αabout␈α"<="?␈αIt␈α␈↓↓still␈↓␈αappears␈αto␈αact␈αlike␈αan␈αassignment␈αstatement.␈α It␈αis␈αtaking␈αon
␈↓ ↓H␈↓more␈α
distinct␈αcharacter␈α
since␈α
it␈αmust␈α
associate␈αenvironments␈α
with␈α
the␈αfunction␈α
body␈αas␈α
it␈α
does␈αthe
␈↓ ↓H␈↓assignment.
␈↓ ↓H␈↓The␈αimplementation␈αof␈α␈↓αfunction␈↓␈αseems␈αlike␈αa␈αlot␈αof␈αwork␈αto␈αallow␈αa␈αmoderately␈αobscure␈αconstruct␈αto
␈↓ ↓H␈↓appear␈α~in␈α→a␈α~language.␈α→ However␈α~constructs␈α→like␈α~functional␈α→arguments␈α~appear␈α~in␈α→several
␈↓ ↓H␈↓programming␈α∞languages␈α
under␈α∞different␈α
guises.␈α∞Usually␈α∞the␈α
syntax␈α∞of␈α
the␈α∞language␈α∞is␈α
sufficiently
␈↓ ↓H␈↓complex␈α↔that␈α_the␈α↔true␈α_behavior␈α↔and␈α↔implications␈α_of␈α↔devices␈α_like␈α↔functional␈α_arguments␈α↔is
␈↓ ↓H␈↓misunderstood.␈α∪Faulty␈α∪implementations␈α∪usually␈α∪result.␈α∩In␈α∪LISP␈α∪the␈α∪problem␈α∪␈↓↓and␈α∪the␈α∩solution␈↓
␈↓ ↓H␈↓appear with exceptional clarity␈↓π 84␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 84␈↓ LISP was the first language to allow functional values.
␈↓ ↓H␈↓␈↓↓134 Evaluation␈↓ )3.10␈↓
␈↓ ↓H␈↓Here is a sketch of the abstract structure of the current ␈↓αeval␈↓.
␈↓ ↓H␈↓αeval <= λ[[exp;environ]
␈↓ ↓H␈↓α␈↓ αx[isvar[exp] → lookup[exp;environ];
␈↓ ↓H␈↓α␈↓ αx isconst[exp] → denote[exp];
␈↓ ↓H␈↓α␈↓ αx iscond[exp] → evcond[args␈↓βc␈↓α[exp];environ];
␈↓ ↓H␈↓α␈↓ αx isfun[exp] → makefunarg[exp;environ];
␈↓ ↓H␈↓α␈↓ αx isfunc+args[exp] → apply[␈↓ ¬Xfunc[exp];
␈↓ ↓H␈↓α␈↓ αx␈↓ ¬Xevlis[arglist[exp];environ];
␈↓ ↓H␈↓α␈↓ αx␈↓ ¬Xenviron]] ]
␈↓ ↓H␈↓α␈↓where:␈↓α
␈↓ ↓H␈↓αapply <= λ[[fn;args,environ]
␈↓ ↓H␈↓α␈↓ αx[isfunname[fn] → ...;
␈↓ ↓H␈↓α␈↓ αx islambda[fn] → eval[␈↓ ¬λbody[fn];
␈↓ ↓H␈↓α␈↓ αx␈↓ ¬λmkenv[vars[fn];args;environ]];
␈↓ ↓H␈↓α␈↓ αx isfunarg[fn] → apply[␈↓ ¬_func␈↓β1␈↓α[fn];
␈↓ ↓H␈↓α␈↓ αx␈↓ ¬λ␈↓ ¬_args;
␈↓ ↓H␈↓α␈↓ αx␈↓ ¬λ␈↓ ¬_evn[fn]];
␈↓ ↓H␈↓α␈↓ αx ... ... ]]
␈↓ ↓H␈↓The␈α
reader␈αis␈α
encouraged␈αto␈α
complete␈αthe␈α
definitions,␈αsupplying␈α
appropriate␈α
constructors,␈αselectors
␈↓ ↓H␈↓and recognizers.
␈↓ ↓H␈↓Now␈α∂for␈α⊂some␈α∂specific␈α∂examples.␈α⊂ Most␈α∂implementations␈α∂of␈α⊂LISP␈α∂include␈α∂a␈α⊂very␈α∂useful␈α⊂class␈α∂of
␈↓ ↓H␈↓mapping functions.
␈↓ ↓H␈↓␈↓αmaplist␈↓␈αis␈α
a␈αfunction␈α
of␈αtwo␈α
arguments:␈α␈↓αfn␈↓,␈α
a␈αunary␈αfunction;␈α
and␈α␈↓αl␈↓,␈α
a␈αlist.␈α
␈α␈↓αmaplist␈↓␈α
applies␈αthe
␈↓ ↓H␈↓␈↓ α8function␈α
␈↓αfn␈↓␈α
to␈α
the␈α
list␈α∞␈↓αl␈↓␈α
and␈α
its␈α
tails␈α
(␈↓αrest[l],␈α
rest[rest[l]], ..␈↓)␈α∞until␈α
␈↓αl␈↓␈α
is␈α
reduced␈α
to␈α∞␈↓α( )␈↓.␈α
The
␈↓ ↓H␈↓␈↓ α8value of ␈↓αmaplist␈↓ is the list of the values returned by ␈↓αfn␈↓. Here's a definition of ␈↓αmaplist␈↓:
␈↓ ↓H␈↓␈↓ β∪␈↓αmaplist <= λ[[fn;l][null[l] → ( ); ␈↓
t␈↓α → concat[fn[l];maplist[fn;rest[l]]]]]␈↓.
␈↓ ↓H␈↓Thus:
␈↓ ↓H␈↓␈↓α␈↓ αmmaplist[function[reverse];(A B C D)] = ((D C B A) (D C B) (D C) (D))␈↓. ␈↓π 85␈↓
␈↓ ↓H␈↓The␈α≡mapping␈α≡functionals␈α≡can␈α≡be␈α≥generalized.␈α≡For␈α≡example␈α≡([Moo 74])␈α≡an␈α≥application
␈↓ ↓H␈↓␈↓αmapfirst[fn;l␈↓β1␈↓α; ...; l␈↓βn␈↓α]␈↓␈αwould␈α
expect␈α␈↓αfn␈↓␈αto␈α
be␈αan␈αn-ary␈α
function␈αto␈αbe␈α
applied␈αto␈αconsecutive␈α
members
␈↓ ↓H␈↓of each ␈↓αl␈↓βi␈↓, building a list of the results of each application.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 85␈↓ The use of ␈↓αfunction␈↓ is unnecessary since ␈↓αreverse␈↓ uses no free variables.
␈↓ ↓H␈↓␈↓↓3.10␈↓ ε⊂Functional Arguments and Functional Values 135␈↓
␈↓ ↓H␈↓An␈α
interesting␈α
and␈α
non-trivial␈α
use␈α
of␈α
functional␈α
arguments␈α
is␈α
shown␈α
on␈α
page 182␈α
where␈α
we␈α
define␈α
a
␈↓ ↓H␈↓new control structure suitable for describing algorithms built to operate on lists.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. What changes should be made to the LISP syntax equations to allow functional arguments?
␈↓ ↓H␈↓II.␈α⊂Use␈α⊂␈↓αapp␈↓␈α⊂on␈α⊃page 129␈α⊂to␈α⊂define␈α⊂a␈α⊂function␈α⊃which␈α⊂computes␈α⊂factorial␈α⊂without␈α⊂using␈α⊃␈↓αlabel␈↓␈α⊂or
␈↓ ↓H␈↓explicit calls on the evaluator.
␈↓ ↓H␈↓III. Extend ␈↓αeval␈↓ and friends to handle functional arguments.
␈↓ ↓H␈↓IV.␈αAn␈αinteresting␈αuse␈αof␈αfunctional␈αarguments␈αinvolves␈αself-applicative␈αfunctions.␈α An␈αapplication
␈↓ ↓H␈↓of␈αa␈αfunction␈α␈↓αf␈↓␈αin␈αa␈αcontext␈α␈↓αf[...;f;...]␈↓␈αis␈αan␈αinstance␈αof␈αself␈αapplication␈α␈↓π 86␈↓.␈αSelf-applicative␈αfunctions
␈↓ ↓H␈↓can␈α⊃be␈α⊃used␈α∩to␈α⊃define␈α⊃recursive␈α⊃functions␈α∩in␈α⊃such␈α⊃a␈α⊃way␈α∩that␈α⊃the␈α⊃definition␈α⊃is␈α∩not␈α⊃␈↓↓statically␈↓
␈↓ ↓H␈↓self-referential,␈αbut␈αis␈α␈↓↓dynamically␈↓␈αre-entrant.␈α For␈αexample,␈αhere␈αis␈αour␈αcanonical␈αexample,␈αwritten
␈↓ ↓H␈↓using a self-applicative function:
␈↓ ↓H␈↓α␈↓ ¬
fact <= λ[[n] f[function[f]; n]]
␈↓ ↓H␈↓α␈↓ ∧@f <= λ[[g;n][n=0 → 1; ␈↓
t␈↓α → *[n; g[g; n-1]] ]]
␈↓ ↓H␈↓Use Weizenbaum's environments to show the execution of ␈↓αfact[2]␈↓.
␈↓ ↓H␈↓V.␈αWrite␈α
a␈αLISP␈αfunction␈α
to␈αfind␈α
the␈αpermutations␈αon␈α
a␈αset␈α
of␈α␈↓αn␈↓␈αelements.␈α
For␈αexample␈α␈↓αperm[(A␈α
B
␈↓ ↓H␈↓αC)]␈↓ gives
␈↓ ↓H␈↓␈↓ β⎇␈↓α((A B C) (A C B) (B C A) (B A C) (C A B) (C B A))␈↓
␈↓ ↓H␈↓VI. Write a generalized form of the ␈↓αdiff␈↓ algorithm (Section 2.3) to handle n-ary sums and products.
␈↓ ↓H␈↓␈↓ ∧≥␈↓↓3.11 Binding Strategies and Implementations␈↓
␈↓ ↓H␈↓After␈αthe␈αdiscussion␈αof␈αvariables␈αin␈αSection 3.7␈αand␈αthe␈αintervening␈αdiscussions␈αof␈αenvironments,␈αit
␈↓ ↓H␈↓should␈αnow␈αbe␈αclear␈αthat␈αthe␈αroot␈αof␈αthe␈αbinding␈αproblem␈αis␈αfree␈αvariables.␈αWe␈αwish␈αto␈α
allow␈αfree
␈↓ ↓H␈↓variables;␈α
many␈α
interesting␈α
algorithms␈α
have␈α
free␈α
variables.␈α
We␈α
don't␈α
want␈α
to␈α
restrict␈α
the␈α
use␈αof␈α
free
␈↓ ↓H␈↓variables␈α
too␈α
precipitously␈α
since␈α
they␈α
are␈α
a␈α
very␈α
useful␈α
programming␈α
technique.␈α
For␈α
example,␈α
the
␈↓ ↓H␈↓possible␈α∪alternative␈α∪of␈α∪passing␈α∪all␈α∪global␈α∪information␈α∪through␈α∪as␈α∪extra␈α∪parameters␈α∪in␈α∪calling
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 86␈↓ provided the designated argument position is a functional argument.
␈↓ ↓H␈↓␈↓↓136 Evaluation␈↓ +3.11␈↓
␈↓ ↓H␈↓sequences is overly expensive␈↓π 87␈↓.
␈↓ ↓H␈↓Handling␈α∂of␈α∂free␈α⊂variables␈α∂varies␈α∂from␈α∂programming␈α⊂language␈α∂to␈α∂programming␈α⊂language.␈α∂ The
␈↓ ↓H␈↓solution␈αadvocated␈αby␈αAlgol-like␈αlanguages␈αis␈αcalled␈α␈↓↓static␈αbinding␈↓␈αor␈α␈↓↓lexical␈αbinding␈↓␈αand␈αdictates
␈↓ ↓H␈↓that␈α
all␈αnon-local␈α
references␈αbe␈α
fixed␈αin␈α
the␈αbinding␈α
environment;␈αthus␈α
free␈αvariables␈α
aren't␈αreally
␈↓ ↓H␈↓free␈αin␈αthe␈α
sense␈αthat␈αwe␈αhave␈α
a␈αchoice␈αto␈αmake.␈α
LISP␈αat␈αleast␈αgives␈α
you␈αa␈αchoice␈↓π 88␈↓.␈α
Using␈α␈↓αquote␈↓
␈↓ ↓H␈↓you␈αwill␈αget␈αthe␈αdynamic␈αbinding␈αon␈α
free␈αvariables␈αin␈αa␈αfunctional␈αargument;␈αusing␈α
␈↓αfunction␈↓␈αgives
␈↓ ↓H␈↓the␈α∩static␈α∪interpretation␈↓π 89␈↓.␈α∩ There␈α∪are␈α∩no␈α∪questions␈α∩about␈α∪Algol's␈α∩interpretation␈α∪of␈α∩functional
␈↓ ↓H␈↓values:␈α⊃the␈α⊃construct␈α⊃is␈α⊃not␈α⊃allowed.␈α⊃When␈α⊃we␈α⊃discuss␈α⊃implementation␈α⊃of␈α⊃binding␈α⊃strategies␈α⊃in
␈↓ ↓H␈↓Chapter 5 we will see why.
␈↓ ↓H␈↓The␈α∀binding␈α∀strategy␈α∪determines␈α∀␈↓↓when␈↓␈α∀the␈α∀variables␈α∪will␈α∀receive␈α∀values;␈α∀the␈α∪implementation
␈↓ ↓H␈↓determines␈α␈↓↓how␈↓␈αthose␈αbindings␈αare␈αto␈αbe␈αaccomplished␈αand␈αtherefore,␈αhow␈αthe␈αlookup␈αof␈α
values␈αis
␈↓ ↓H␈↓to␈α be␈α!accomplished.␈α We␈α have␈α!seen␈α one␈α implementation␈α!in␈α the␈α!␈↓αassoc - pairlis␈↓␈α pair
␈↓ ↓H␈↓(Section 3.5, page 109),␈α⊂and␈α⊃on␈α⊂page 120␈α⊂suggested␈α⊃a␈α⊂related␈α⊂implementation␈α⊃using␈α⊂Weizenbaum
␈↓ ↓H␈↓environments. Now we examine another implementation.
␈↓ ↓H␈↓The␈αmost␈αgeneral␈αenvironment␈αstructure␈αwhich␈αLISP␈αcreates␈αis␈αa␈αtree␈αof␈αlocal␈αsymbol␈αtables,␈αrooted
␈↓ ↓H␈↓in␈α∪the␈α∪global␈α∩table.␈α∪The␈α∪typical␈α∩LISP␈α∪computation␈α∪generates␈α∩a␈α∪single␈α∪branch,␈α∪but␈α∩functional
␈↓ ↓H␈↓arguments␈αand␈αvalues␈αcan␈αgenerate␈αadditional␈αbranches.␈αLocating␈αa␈αvariable␈α␈↓αn␈↓␈α
involved␈αsearching
␈↓ ↓H␈↓the␈α
current␈α
branch␈αfrom␈α
tip␈α
to␈α
root,␈αlooking␈α
for␈α
the␈α
first␈αoccurrence␈α
of␈α
␈↓αn␈↓.␈α
If␈α␈↓αn␈↓␈α
was␈α
bound␈αvery␈α
deep,
␈↓ ↓H␈↓the␈αsearch␈αcould␈αbe␈αlong.␈α Indeed␈αthe␈αtime␈αis␈αproportional␈αto␈αthe␈αdepth␈αof␈αthe␈αbranch.␈αIt␈αhas␈αbeen
␈↓ ↓H␈↓noted␈α[Wegb 75]␈αthat␈αvariables␈αtend␈α
to␈αbe␈αrebound␈αrather␈αseldom;␈α
there␈αare␈αfew␈αoccurrences␈αof␈α
any
␈↓ ↓H␈↓given␈α∞variable␈α∞on␈α∞any␈α
particular␈α∞branch.␈α∞ If␈α∞this␈α
is␈α∞the␈α∞case,␈α∞then␈α
the␈α∞search␈α∞will␈α∞examine␈α
many
␈↓ ↓H␈↓environment␈α
blocks␈α
which␈α
do␈α
not␈α
contain␈α
the␈αdesired␈α
variable.␈α
If␈α
the␈α
number␈α
of␈α
bindings␈α
of␈αany
␈↓ ↓H␈↓variable␈α
is␈α
small␈α
compared␈α
to␈αthe␈α
number␈α
of␈α
environment␈α
blocks␈αwhich␈α
have␈α
to␈α
be␈α
searched␈αto␈α
find
␈↓ ↓H␈↓those␈α⊂bindings,␈α∂then␈α⊂we␈α∂would␈α⊂like␈α∂a␈α⊂viable␈α∂alternative␈α⊂to␈α∂the␈α⊂␈↓αassoc - pairlis␈↓␈α⊂implementation␈α∂of
␈↓ ↓H␈↓␈↓αlookup - mkenv␈↓.␈α
That␈α
is,␈α
a␈α
scheme␈α
whose␈α
search␈α
is␈α
proportional␈α
to␈α
the␈α
number␈α
of␈α
bindings␈α
for␈αa
␈↓ ↓H␈↓variable, rather than proportional to the depth of the tree. There is such an alternative.
␈↓ ↓H␈↓Namely,␈α∞we␈α∞associate␈α∞␈↓↓all␈↓␈α∞the␈α∞values␈α∞possessed␈α∞by␈α∞␈↓αn␈↓␈α∞with␈α∞␈↓αn␈↓␈α∞itself.␈α∞ To␈α∞signify␈α∂which␈α∞environment
␈↓ ↓H␈↓created␈α
the␈α
binding,␈α
we␈α
associate␈α
pairs␈α
consisting␈α
of␈α
the␈α
value␈α
and␈α
the␈α
environment␈α∞name.␈α
Thus
␈↓ ↓H␈↓the␈αnew␈α␈↓αmkenv[vars;vals;env]␈↓␈αapplication␈α
must␈αname␈αa␈αnew␈αenvironment,␈α
call␈αit␈α␈↓αnew␈↓,␈αand␈α
attach␈αit
␈↓ ↓H␈↓to␈αthe␈αtip␈αof␈αthe␈αcurrent␈αbranch␈αin␈αthe␈αenvironment␈αtree.␈αAlso,␈αfor␈αeach␈αentry␈αin␈α␈↓αvals␈↓,␈α
␈↓αmkenv␈↓␈αmust
␈↓ ↓H␈↓associate a value-␈↓αnew␈↓ pair with each name in ␈↓αvars␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 87␈↓ Though much of that expense can be mitigated by a clever compiler.
␈↓ ↓H␈↓␈↓π 88␈↓␈α
However␈α
[Ste 76b]␈α
shows␈α
that␈α
dynamic␈α
binding␈α
can␈α
be␈α
simulated␈α
in␈α
a␈α
statically␈α
bound␈α
LISP-like
␈↓ ↓H␈↓language.
␈↓ ↓H␈↓␈↓π 89␈↓␈αA␈αcase␈αcan␈αbe␈αmade␈αfor␈αeven␈αmore␈αflexibility␈αin␈αthe␈αinterpretation␈αof␈αfree␈αvariables.␈α
We␈αcould
␈↓ ↓H␈↓ask␈α
that␈α
the␈α
binding␈αbe␈α
done␈α
on␈α
a␈αper␈α
variable␈α
basis.␈α
That␈α
is␈αwe␈α
could␈α
declare␈α
which␈αfree␈α
variables
␈↓ ↓H␈↓are␈α∞to␈α∞be␈α∞captured␈α∞statically␈α∞and␈α∞which␈α∞are␈α∞to␈α∞be␈α∞captured␈α∞dynamically.␈α∞ We␈α∞could␈α∞also␈α∞ask␈α
that
␈↓ ↓H␈↓␈↓↓both␈↓␈α
bindings␈αbe␈α
available␈αand␈α
supply␈α
selectors␈αwhich␈α
would␈αaccess␈α
either␈α
the␈αdynamic␈α
or␈αthe␈α
static
␈↓ ↓H␈↓binding.
␈↓ ↓H␈↓␈↓↓3.11␈↓ εUBinding Strategies and Implementations 137␈↓
␈↓ ↓H␈↓The␈α␈↓αlookup␈↓␈αprocedure␈αis␈αgiven␈αthe␈αname␈α␈↓αn␈↓␈α
and␈αa␈αbranch␈αin␈αthe␈αenvironment␈αtree.␈αAssume␈αthat␈α
the
␈↓ ↓H␈↓tip␈αnode␈αof␈αthe␈αtree␈α
is␈αnamed␈αEnv.␈α If␈α␈↓αn␈↓␈αhas␈α
an␈αattached␈αvalue␈αpair␈αwhose␈αenvironment␈α
component
␈↓ ↓H␈↓is␈α⊂Env,␈α⊂then␈α⊂the␈α⊂associated␈α⊂value␈α⊂is␈α⊂returned␈α⊂by␈α⊂␈↓αlookup␈↓.␈α⊂Otherwise␈α⊂the␈α⊂environment␈α⊃branch␈α⊂is
␈↓ ↓H␈↓searched␈α
recursively␈α
by␈α
␈↓αlookup␈↓␈α
looking␈α
for␈α
the␈α
first␈α
node␈α
in␈α
that␈α
branch␈α
which␈α
has␈α∞an␈α
associated
␈↓ ↓H␈↓value attached to ␈↓αn␈↓.
␈↓ ↓H␈↓Here's a graphical description of this reorganization of our symbol tables:
␈↓"␈↓ ↓H␈↓α␈↓ ¬≡␈↓↓ The ␈↓αassoc-pairlis ␈↓↓structure
␈↓"␈↓ ↓H␈↓
E1 E2 E4
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ⊂αααπααα⊃ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
~ x ~ 3 ~ ~ y ~ 4 ~ ~ x ~ C ~
␈↓"␈↓ ↓H␈↓
εαααβαααλ %αααβααα$ %αααβααα$
␈↓"␈↓ ↓H␈↓
~ y ~ 1 ~ ~ ↓
␈↓"␈↓ ↓H␈↓
εαααβαααλ ↓ E3
␈↓"␈↓ ↓H␈↓
~ z ~ A ~ ~ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
%αααβααα$ ~ ~ z ~ 4 ~
␈↓"␈↓ ↓H␈↓
~ ~ %αααβααα$
␈↓"␈↓ ↓H␈↓
↓ ↓ ↓
␈↓"␈↓ ↓H␈↓
~ E0 ~
␈↓"␈↓ ↓H␈↓
%ααααα→αααα→⊂αααπααα⊃←αααα←αααα$
␈↓"␈↓ ↓H␈↓
~ y ~ 2 ~
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ z ~ 1 ~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓↓␈↓ ¬KThe new structures
␈↓"␈↓ ↓H␈↓
x y z
␈↓"␈↓ ↓H␈↓
E1 E4 ⊂ααααπααα⊃ ⊂ααααπααα⊃ ⊂ααααπααα⊃
␈↓"␈↓ ↓H␈↓
↓ E2 ↓ ~ E1 ~ 3 ~ ~ E0 ~ 2 ~ ~ E0 ~ 1 ~
␈↓"␈↓ ↓H␈↓
\ ~ E3 εααααβαααλ εααααβαααλ εααααβαααλ
␈↓"␈↓ ↓H␈↓
\ ↓ / ~ E4 ~ C ~ ~ E1 ~ 1 ~ ~ E1 ~ A ~
␈↓"␈↓ ↓H␈↓
\~/ %αααα∀ααα$ εααααβαααλ εααααβαααλ
␈↓"␈↓ ↓H␈↓
↓ ~ E2 ~ 4 ~ ~ E3 ~ 4 ~
␈↓"␈↓ ↓H␈↓
E0 %αααα∀ααα$ %αααα∀ααα$
␈↓ ↓H␈↓Using the discussion of ␈↓αmkenv␈↓ on page 109, we define:
␈↓ ↓H␈↓α␈↓ ¬>alloc <=λ[[x] gensym[]]
␈↓ ↓H␈↓α␈↓ ∧[link <= λ[[block;env] concat[block;env]]
␈↓ ↓H␈↓α␈↓ ∧↔send <= λ[[n;v;blk] addval[n;mkent[first[blk];v]]]
␈↓ ↓H␈↓The␈α∞function␈α∂␈↓αgensym␈↓␈α∞is␈α∞to␈α∂generate␈α∞a␈α∂new␈α∞environment␈α∞name␈α∂which␈α∞␈↓αalloc␈↓␈α∞makes␈α∂into␈α∞a␈α∂new␈α∞tip
␈↓ ↓H␈↓node on the end of the current environment branch.
␈↓ ↓H␈↓The function ␈↓αaddval␈↓ adds a new entry to the variable ␈↓αn␈↓. The value of ␈↓αaddval␈↓ is ␈↓αenv␈↓.
␈↓ ↓H␈↓␈↓↓138 Evaluation␈↓ +3.11␈↓
␈↓ ↓H␈↓The␈α⊂new␈α⊂␈↓αlookup␈↓␈α⊂is␈α⊂more␈α∂complicated␈α⊂than␈α⊂the␈α⊂simple␈α⊂␈↓αassoc␈↓.␈α∂Given␈α⊂a␈α⊂node␈α⊂in␈α⊂the␈α∂environment
␈↓ ↓H␈↓branch,␈αwe␈αmust␈αsee␈αif␈αthere␈α
is␈αa␈αrelated␈αbinding␈αfor␈α␈↓αn␈↓.␈αIf␈α
there␈αis,␈αthen␈αthat's␈αthe␈αbinding␈αwe␈α
want.
␈↓ ↓H␈↓If no binding is found we look at the next deeper node on the tree, and check its bindings.
␈↓ ↓H␈↓αlookup <= λ[[n;env] λ[[z] look␈↓λ'␈↓α[z;z;env]][getval[n]] ]
␈↓ ↓H␈↓αlook␈↓λ'␈↓α <= λ[[l;l1;env]␈↓ βH[null[l] →look␈↓λ'␈↓α[l1;l1;rest[env]]
␈↓ ↓H␈↓α␈↓ βH eq[name[first[l]];first[env]] → value[first[l]]
␈↓ ↓H␈↓α␈↓ βH ␈↓
t␈↓α → look␈↓λ'␈↓α[rest[l];l1;env] ]]
␈↓ ↓H␈↓This␈α∞new␈α
scheme␈α∞is␈α
called␈α∞␈↓↓shallow␈α
binding␈↓,␈α∞and␈α
the␈α∞␈↓αassoc-pairlis␈↓␈α
scheme␈α∞is␈α
called␈α∞␈↓↓deep␈α
binding␈↓.
␈↓ ↓H␈↓The␈αessential␈αdifferences␈αbetween␈αthese␈αtwo␈αbinding␈αimplementations␈αis␈αthat␈αa␈αdeep␈αbinding␈αsearch
␈↓ ↓H␈↓is␈α∪keyed␈α∪on␈α∪the␈α∪name␈α∪of␈α∪the␈α∀variable,␈α∪whereas␈α∪a␈α∪shallow␈α∪binding␈α∪strategy␈α∪is␈α∪keyed␈α∀on␈α∪the
␈↓ ↓H␈↓environment␈α∂name.␈α∂These␈α∂requirements␈α∂have␈α∞corresponding␈α∂implications␈α∂for␈α∂the␈α∂organization␈α∞of
␈↓ ↓H␈↓the symbol tables␈↓π 90␈↓.
␈↓ ↓H␈↓A␈α
further␈α
elaboration␈αof␈α
the␈α
shallow␈α
scheme␈αis␈α
possible.␈α
The␈α
essential␈αaim␈α
of␈α
shallow␈α
binding␈αis␈α
the
␈↓ ↓H␈↓reduction␈α
of␈α
the␈α
search␈α
time␈α
for␈α
values␈α
of␈α
variables.␈α
The␈α
current␈α
scheme␈α
improves␈α∞the␈α
situation,
␈↓ ↓H␈↓but␈αif␈αa␈αvariable␈αis␈αbound␈αseveral␈αtimes␈α
we␈αstill␈αmay␈αhave␈αto␈αsearch␈αthe␈αtable␈αof␈α
values␈αassociated
␈↓ ↓H␈↓with␈αthe␈αatom.␈α The␈α
next␈αmodification␈αarranges␈αthat␈α
the␈αcorrect␈αbinding␈αis␈α
always␈αfound␈αin␈αa␈α
fixed
␈↓ ↓H␈↓location␈α
associated␈α
with␈α
the␈α
atom.␈α
As␈α
with␈α
any␈α
scheme,␈α
the␈α
benefits␈α
are␈α
not␈α
without␈α
penalty;␈α
we␈α
will
␈↓ ↓H␈↓discuss some of the trade offs after we describe the implementation.
␈↓ ↓H␈↓With␈α
each␈α
variable␈α
␈↓αn␈↓␈αwe␈α
associate␈α
a␈α
␈↓↓single␈↓␈α
entry␈αcalled␈α
the␈α
␈↓↓value cell␈↓.␈α
The␈α
binding␈αand␈α
unbinding
␈↓ ↓H␈↓mechanisms␈α⊂will␈α⊂maintain␈α∂the␈α⊂correct␈α⊂value␈α∂of␈α⊂the␈α⊂variable␈α∂in␈α⊂the␈α⊂value␈α∂cell.␈α⊂The␈α⊂scheme␈α⊂is␈α∂a
␈↓ ↓H␈↓mixture of the two previous implementations.
␈↓ ↓H␈↓The ␈↓αlookup␈↓ routine is similar to the shallow lookup:
␈↓ ↓H␈↓α␈↓ ∧tlookup <= λ[[x;env] getval_cell[x]]
␈↓ ↓H␈↓Notice that ␈↓αenv␈↓ is ignored in ␈↓αlookup␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 90␈↓␈α⊃The␈α⊃table␈α⊃organization␈α⊃discussed␈α⊃in␈α⊃this␈α∩section␈α⊃was␈α⊃also␈α⊃used␈α⊃in␈α⊃a␈α⊃language␈α∩named␈α⊃LC␈↓π2␈↓
␈↓ ↓H␈↓([Mit 70]).␈αIn␈αtheir␈αterminology,␈α"deep␈αtable"␈αwas␈αcalled␈α"scope␈αoriented␈αorganization"␈αand␈α"shallow
␈↓ ↓H␈↓table" was called "name oriented organization".
␈↓ ↓H␈↓␈↓↓3.11␈↓ εUBinding Strategies and Implementations 139␈↓
␈↓ ↓H␈↓The␈αbinding␈αroutine␈αis␈α
a␈αbit␈αmore␈αcomplex.␈α
When␈αbinding␈α␈↓αn␈↓␈αwe␈α
have␈αto␈αreplace␈αthe␈αcurrent␈α
value
␈↓ ↓H␈↓cell␈αwith␈αthe␈αnew␈αbinding.␈α We␈αalso␈αhave␈αto␈αsave␈αthe␈αold␈αbinding␈αso␈αthat␈αit␈αmay␈αbe␈αrestored␈αwhen
␈↓ ↓H␈↓the␈α∩sub-computation␈α∩is␈α∩completed;␈α∪this␈α∩part␈α∩of␈α∩the␈α∪implementation␈α∩is␈α∩like␈α∩deep␈α∪binding.␈α∩ We
␈↓ ↓H␈↓perform␈α∞most␈α
of␈α∞the␈α∞␈↓αmkenv␈↓␈α
operations␈α∞as␈α∞given␈α
on␈α∞page 109,␈α
but␈α∞require␈α∞a␈α
new␈α∞version␈α∞of␈α
␈↓αsend␈↓.
␈↓ ↓H␈↓Instead␈αof␈αplacing␈αthe␈αnew␈αbindings␈αin␈αthe␈α
block␈αbuilt␈αby␈α␈↓αsend␈↓,␈αwe␈αplace␈αthe␈αcurrent␈αbindings␈α
there
␈↓ ↓H␈↓as we place the new bindings in the value cell.
␈↓ ↓H␈↓α␈↓ βεsend <= λ[[var;val;block] concat[mkent[var;swp_val_cell[var;val]];block]]
␈↓ ↓H␈↓where ␈↓αsw_val_cell␈↓ places ␈↓αval␈↓ in the value cell of ␈↓αvar␈↓ and returns to old value.
␈↓ ↓H␈↓The␈αunbinding␈αoperation␈αis␈αeven␈αmore␈αcomplicated.␈αWhen␈αwe␈αleave␈αan␈αenvironment␈αwe␈αexpect␈αthe
␈↓ ↓H␈↓prior␈α∪environment␈α∩to␈α∪be␈α∩re-established.␈α∪That␈α∩is␈α∪done␈α∩automatically␈α∪by␈α∩recursion␈α∪in␈α∪the␈α∩deep
␈↓ ↓H␈↓implementation␈α
and␈α
in␈α
the␈α
previous␈α
shallow␈α
binder.␈α
See␈α
page 104;␈α
the␈α
recursive␈α
call␈α
on␈α
␈↓αeval␈↓␈α
with
␈↓ ↓H␈↓the new binding of ␈↓αenviron␈↓ will lose its effect as we leave ␈↓αeval␈↓.
␈↓ ↓H␈↓However,␈α
the␈α
new␈αscheme␈α
requires␈α
more;␈αwe␈α
must␈α
restore␈αthe␈α
saved␈α
values␈αto␈α
the␈α
value␈α
cells,␈αand
␈↓ ↓H␈↓recursion␈α∂will␈α∂not␈α∂do␈α∂that␈α∂automatically.␈α∂ We␈α⊂will␈α∂discuss␈α∂more␈α∂of␈α∂the␈α∂details␈α∂of␈α∂this␈α⊂process␈α∂in
␈↓ ↓H␈↓Section 3.11␈α∞and␈α
Section 5.19,␈α∞but␈α
the␈α∞basic␈α
idea␈α∞is␈α
to␈α∞swap␈α
the␈α∞contents␈α
of␈α∞the␈α
saved␈α∞block␈α
back
␈↓ ↓H␈↓into␈αthe␈αvalue␈α
cells␈αas␈αwe␈αleave␈α
the␈αinner␈αcall␈αon␈α
␈↓αeval␈↓.␈αNotice␈αthat␈αwe␈α
cannot␈αsimply␈αthrow␈αaway␈α
the
␈↓ ↓H␈↓old␈αbindings␈αsince␈αa␈αcall␈αon␈α␈↓αfunction␈↓␈αmay␈αhave␈αoccurred.␈αThe␈α␈↓αfunarg␈↓␈αtriple␈αcan␈αbe␈αbuilt␈αas␈αbefore:
␈↓ ↓H␈↓saving␈αthe␈αcurrent␈αenvironment␈αname␈α(␈↓↓not␈↓␈αsaving␈αthe␈αcurrent␈αcontents␈αof␈αall␈αthe␈αvalue␈αcells).␈α The
␈↓ ↓H␈↓application␈αof␈α␈↓αfunarg␈↓s␈αis␈αtherefore␈αmore␈αproblematic.␈αIn␈αthe␈αprevious␈αbinding␈αimplementations,␈αall
␈↓ ↓H␈↓we␈α⊂needed␈α⊂to␈α∂do␈α⊂was␈α⊂establish␈α∂the␈α⊂saved␈α⊂environment␈α∂name␈α⊂as␈α⊂the␈α∂evironment␈α⊂to␈α⊂be␈α⊂used␈α∂for
␈↓ ↓H␈↓non-local␈α∞searches.␈α∞ In␈α
this␈α∞latest␈α∞binder,␈α∞we␈α
must␈α∞␈↓↓re-establish␈↓␈α∞the␈α
value␈α∞cells␈α∞which␈α∞were␈α
current
␈↓ ↓H␈↓when␈α~␈↓αfunction␈↓␈α→was␈α~recognized.␈α→ We␈α~will␈α→postpone␈α~this␈α→discussion␈α~until␈α~Section 5.19␈α→and
␈↓ ↓H␈↓Section 5.20.
␈↓ ↓H␈↓This␈α
latest␈αimplementation␈α
of␈αbinding␈α
is␈αby␈α
far␈αthe␈α
most␈αcomplex␈α
we␈αhave␈α
seen.␈α It␈α
gives␈αfast␈α
access
␈↓ ↓H␈↓to␈α⊃values␈α⊃of␈α⊂variables,␈α⊃but␈α⊃requires␈α⊂more␈α⊃effort␈α⊃in␈α⊂changing␈α⊃environments;␈α⊃that␈α⊃is␈α⊂particularly
␈↓ ↓H␈↓evident␈α∪in␈α∩the␈α∪discussion␈α∪of␈α∩␈↓αfunction␈↓ constructs.␈α∪ We␈α∩will␈α∪discuss␈α∪the␈α∩relative␈α∪merits␈α∪of␈α∩these
␈↓ ↓H␈↓implementations␈α∩in␈α∩more␈α∩detail␈α∩in␈α∩Chapter 5.␈α⊃ Be␈α∩clear␈α∩on␈α∩the␈α∩distinction␈α∩between␈α∩a␈α⊃binding
␈↓ ↓H␈↓strategy␈αand␈αa␈αbinding␈αimplementation.␈α The␈αtwo␈αstrategies␈αwe␈αhave␈αdiscussed␈αare␈αcalled␈α"dynamic"
␈↓ ↓H␈↓and␈α∪"static";␈α∪the␈α∪two␈α∪implementations␈α∀are␈α∪called␈α∪"deep"␈α∪and␈α∪"shallow".␈α∀Either␈α∪implementation
␈↓ ↓H␈↓technique can be used with either binding strategy.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Suggest an implementation of ␈↓αaddval␈↓ which will improve the search efficiency of ␈↓αlookup␈↓.
␈↓ ↓H␈↓II.␈α
Analyze␈α
␈↓αlookup␈↓␈α
in␈α
a␈αmanner␈α
similar␈α
to␈α
that␈α
performed␈αon␈α
␈↓αmkenv␈↓␈α
on␈α
page 109.␈α
Identify␈αthe␈α
parts
␈↓ ↓H␈↓␈↓↓140 Evaluation␈↓ +3.11␈↓
␈↓ ↓H␈↓of␈α∂␈↓αlookup␈↓␈α∂which␈α∂are␈α∂independent␈α∂of␈α∞the␈α∂binding␈α∂implementation.␈α∂Rewrite␈α∂the␈α∂shallow␈α∂and␈α∞deep
␈↓ ↓H␈↓versions of ␈↓αlookup␈↓ in this more general setting.
␈↓ ↓H␈↓␈↓ ∧⎇␈↓↓3.12 Special Forms and Macros␈↓
␈↓ ↓H␈↓We␈α∪have␈α∪remarked␈α∀that␈α∪the␈α∪evaluation␈α∀scheme␈α∪for␈α∪LISP␈α∀functions␈α∪is␈α∪call-by-value␈α∀and,␈α∪for
␈↓ ↓H␈↓functions␈α⊂with␈α⊂multiple␈α⊂arguments,␈α∂left-to-right␈α⊂evaluation␈α⊂of␈α⊂arguments.␈α∂We␈α⊂have␈α⊂also␈α⊂seen,␈α∂in
␈↓ ↓H␈↓␈↓αquote␈↓␈αand␈α␈↓αcond␈↓,␈αthat␈αnot␈αall␈αforms␈αto␈αbe␈αevaluated␈αin␈αLISP␈αfall␈αwithin␈αthis␈αcategory.␈α The␈αpurpose
␈↓ ↓H␈↓of␈α∂␈↓αquote␈↓␈α∂was␈α∞to␈α∂␈↓↓stop␈↓␈α∂evaluation.␈α∂ The␈α∞"argument␈α∂list"␈α∂to␈α∂␈↓αcond␈↓␈α∞is␈α∂also␈α∂handled␈α∂differently.␈α∞ Since
␈↓ ↓H␈↓␈↓αquote␈↓␈α
and␈α
␈↓αcond␈↓␈αwere␈α
rather␈α
anomalous␈α
we␈αhave␈α
called␈α
them␈α
␈↓↓special␈αforms␈↓.␈α
However,␈α
now␈αwe␈α
would
␈↓ ↓H␈↓like to discuss special forms as a general technique.
␈↓ ↓H␈↓Consider␈α
the␈α∞predicates␈α
␈↓αand␈↓␈α
and␈α∞␈↓αor␈↓.␈α
We␈α
might␈α∞wish␈α
to␈α
define␈α∞␈↓αand␈↓␈α
to␈α
be␈α∞a␈α
binary␈α∞predicate␈α
such
␈↓ ↓H␈↓that␈α␈↓αand␈↓␈αis␈α
true␈αjust␈αin␈α
case␈α␈↓↓both␈↓␈αarguments␈αevaluate␈α
to␈α␈↓
t␈↓,␈αand␈α
define␈α␈↓αor␈↓␈αto␈α
be␈αbinary␈αand␈αfalse␈α
just
␈↓ ↓H␈↓in␈αcase␈α
both␈αarguments␈α
evaluate␈αto␈α
␈↓
f␈↓.␈α Notice␈α
two␈αpoints.␈α
First,␈αthere␈α
is␈αreally␈α
no␈αreason␈α
to␈αrestrict
␈↓ ↓H␈↓these␈α
predicates␈α
to␈α
be␈α
␈↓↓binary␈↓.␈αReplacing␈α
the␈α
words␈α
"binary"␈α
by␈α"n-ary"␈α
and␈α
"both"␈α
by␈α
"all"␈α
in␈αthe
␈↓ ↓H␈↓above␈αdescription␈αhas␈αthe␈αdesired␈αeffect.␈α
Second,␈αif␈αwe␈αevaluate␈αthe␈αarguments␈αto␈α
these␈αpredicates
␈↓ ↓H␈↓in␈α
some␈αorder,␈α
say␈αleft-to-right,␈α
then␈α
we␈αcould␈α
immediately␈αdetermine␈α
that␈α
␈↓αand␈↓␈αis␈α
false␈αas␈α
soon␈αas␈α
we
␈↓ ↓H␈↓come␈α∞across␈α
an␈α∞argument␈α
which␈α∞evaluates␈α
to␈α∞␈↓
f␈↓;␈α
similarly␈α∞a␈α
call␈α∞on␈α
␈↓αor␈↓␈α∞for␈α
an␈α∞arbitrary␈α∞number␈α
of
␈↓ ↓H␈↓arguments␈αcan␈αbe␈αterminated␈αas␈αsoon␈αas␈αwe␈αevaluate␈αan␈αargument␈αgiving␈αvalue␈α␈↓
t␈↓.␈α But␈αif␈αwe␈αinsist
␈↓ ↓H␈↓that␈α␈↓αand␈↓␈α
and␈α␈↓αor␈↓␈αbe␈α
LISP␈α␈↓↓functions␈↓␈αwe␈α
can␈αtake␈α
advantage␈αof␈αneither␈α
of␈αthese␈αobservations.␈α
Rather
␈↓ ↓H␈↓we␈αwill␈αdefine␈α␈↓αand␈↓␈αand␈α␈↓αor␈↓␈αas␈αspecial␈αforms␈αand␈αhandle␈αthe␈αevaluation␈αourselves.␈αPresently,␈αthe␈αonly
␈↓ ↓H␈↓way to handle special forms is to make explicit modifications to ␈↓αeval␈↓␈↓π 91␈↓.
␈↓ ↓H␈↓α␈↓Recognizers for the predicates must be added to ␈↓αeval␈↓:
␈↓ ↓H␈↓αisand[e] → evand[arglist[e];environ];
␈↓ ↓H␈↓αisor[e] → evor[arglist[e];environ];
␈↓ ↓H␈↓α␈↓where:␈↓α
␈↓ ↓H␈↓αevand <= λ[[l;a]␈↓ β_[null[l]→ ␈↓
t␈↓α;
␈↓ ↓H␈↓α␈↓ β_ eval[first[l];a] → evand[rest[l];a];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → ␈↓
f␈↓α] ]
␈↓ ↓H␈↓αevor <= λ[[l;a]␈↓ β_[null[l] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ β_ eval[first[l];a] → ␈↓
t␈↓α;
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → evor[rest[l];a]] ]
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 91␈↓␈α∩On␈α∩page 197␈α⊃and␈α∩in␈α∩Section 4.10␈α∩we␈α⊃will␈α∩discuss␈α∩simple␈α∩ways␈α⊃to␈α∩add␈α∩such␈α∩forms␈α⊃without
␈↓ ↓H␈↓modifying ␈↓αeval␈↓.
␈↓ ↓H␈↓␈↓↓3.12␈↓ λ↔Special Forms and Macros 141␈↓
␈↓ ↓H␈↓Or, exploiting the duality of ␈↓αand␈↓ and ␈↓αor␈↓ ([Ste pc]):
␈↓ ↓H␈↓αisand[e] → evandor[arglist[e];environ;␈↓
t␈↓α];
␈↓ ↓H␈↓αisor[e] → evandor[arglist[e];environ;␈↓
f␈↓α];
␈↓ ↓H␈↓αevandor <= λ[[l;a;d]␈↓ βX[null[l] → d;
␈↓ ↓H␈↓α␈↓ βX xor[d;eval[first[l];a]] → not[d];
␈↓ ↓H␈↓α␈↓ βX ␈↓
t␈↓α → evandor[rest[l];a;d]]]
␈↓ ↓H␈↓αxor <= λ[[a;b][a → not[b]; ␈↓
t␈↓α → b]]
␈↓ ↓H␈↓In either formulation there are explicit calls on ␈↓αeval␈↓␈↓π 92␈↓. This is expensive, but cannot be helped.
␈↓ ↓H␈↓Special␈α∂forms␈α⊂have␈α∂been␈α⊂used␈α∂for␈α⊂two␈α∂purposes:␈α⊂one␈α∂is␈α⊂to␈α∂control␈α⊂the␈α∂evaluation␈α⊂of␈α∂arguments;
␈↓ ↓H␈↓conditional␈αexpressions,␈αquoted␈αexpressions,␈α␈↓αand␈↓,and␈α␈↓αor␈↓␈αare␈αexamples.␈αThe␈αsecond␈α
application␈αarea
␈↓ ↓H␈↓is␈α∂to␈α⊂create␈α∂the␈α⊂effect␈α∂of␈α⊂call-by-value␈α∂functions␈α⊂with␈α∂an␈α⊂indefinite␈α∂number␈α⊂of␈α∂arguments␈α⊂␈↓↓all␈↓␈α∂of
␈↓ ↓H␈↓which are to be evaluated; the LISP functions, ␈↓αlist, append␈↓, and ␈↓αplus␈↓ are examples in this category.
␈↓ ↓H␈↓Even␈αthough␈αwe␈α
wish␈αto␈αdefine␈αthese␈α
functions␈αas␈αif␈αthey␈α
had␈αan␈αarbitrary␈αnumber␈α
of␈αarguments,
␈↓ ↓H␈↓when we ␈↓↓call␈↓ the function, the number of arguments to be applied ␈↓↓is␈↓ known␈↓π 93␈↓.
␈↓ ↓H␈↓Assume,␈α
for␈αexample,␈α
we␈α
wish␈αto␈α
define␈α␈↓αplus␈↓␈α
as␈α
a␈αfunction␈α
with␈α
an␈αindefinite␈α
number␈αof␈α
arguments
␈↓ ↓H␈↓such that:
␈↓ ↓H␈↓α␈↓ ¬zplus[4;5] = 9
␈↓ ↓H␈↓α␈↓ ¬gplus[4;5;6] = 15
␈↓ ↓H␈↓α␈↓ ¬Cplus[4;add1[2];4] = 11
␈↓ ↓H␈↓We can define ␈↓αplus␈↓ in terms of a ␈↓↓binary␈↓ addition function, ␈↓α*plus␈↓.
␈↓ ↓H␈↓α␈↓ ¬&plus[4;5] = *plus[4;5] = 9
␈↓ ↓H␈↓α␈↓ ∧Xplus[4;5;6] = *plus[4;*plus[5;6]] = 15
␈↓ ↓H␈↓α␈↓ ∧∞plus[4;add1[2];4] = *plus[4;*plus[add1[2];4]] = 11
␈↓ ↓H␈↓We␈α␈↓↓expand␈↓␈αcalls␈αon␈α␈↓αplus␈↓␈αinto␈αa␈αcomposition␈αof␈αcalls␈αon␈α␈↓α*plus␈↓.␈α ␈↓αplus␈↓␈αis␈αbeing␈αused␈αas␈αa␈α␈↓↓macro␈↓␈αand
␈↓ ↓H␈↓the␈α
expansion␈α
process␈α
in␈α
terms␈α
of␈α␈↓α*plus␈↓␈α
is␈α
called␈α
␈↓↓macro␈α
expansion␈↓.␈α
The␈α
macro␈αexpansion␈α
generates
␈↓ ↓H␈↓a composition of calls on ␈↓α*plus␈↓.
␈↓ ↓H␈↓A␈α⊃macro␈α⊂is␈α⊃a␈α⊂λ-expression␈α⊃of␈α⊃␈↓↓one␈↓␈α⊂argument.␈α⊃The␈α⊂␈↓↓use␈↓␈α⊃of␈α⊃a␈α⊂macro␈α⊃looks␈α⊂just␈α⊃like␈α⊃an␈α⊂ordinary
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 92␈↓␈αAlso␈αnotice␈αthat␈αthe␈αabstract␈αversions␈α
of␈α␈↓αevand␈↓,␈α␈↓αevor␈↓␈αand␈α␈↓αevandor␈↓␈α␈↓↓know␈↓␈αthat␈αthe␈α
arguments␈αare
␈↓ ↓H␈↓represented as a sequence and the structure of the recursion implies a left-to-right evaluation.
␈↓ ↓H␈↓␈↓π 93␈↓␈αIn␈αparticular,␈α
when␈αthe␈αcompiler␈α
is␈αexamining␈αthe␈α
program,␈αthe␈αnumber␈α
of␈αarguments␈αis␈α
known,
␈↓ ↓H␈↓and as a result, the compiler can often generate more knowledgeable code than just calls on ␈↓αeval␈↓.
␈↓ ↓H␈↓␈↓↓142 Evaluation␈↓ )3.12␈↓
␈↓ ↓H␈↓function␈α
call,␈αbut␈α
what␈α
is␈αbound␈α
to␈αthe␈α
λ-variable␈α
is␈αthe␈α
whole␈αcall␈α
on␈α
the␈αmacro␈↓π 94␈↓.␈α
The␈α
task␈αof
␈↓ ↓H␈↓the␈αmacro␈α
body␈αis␈α
to␈αexpand␈α
the␈αmacro␈α
call␈αand␈α
return␈αthis␈α
expansion␈αas␈α
its␈αvalue.␈α This␈α
expanded
␈↓ ↓H␈↓form␈αis␈αpassed␈αback␈αthrough␈α␈↓αeval␈↓␈αto␈αcomplete␈αthe␈αcomputation.␈α In␈αSection 4.10␈αwe␈αwill␈αdiscuss␈αthe
␈↓ ↓H␈↓additional mechanisms which evaluators must possess for execution of macros.
␈↓ ↓H␈↓Let's␈αdefine␈α␈↓α<␈↓βm␈↓α=␈↓␈α
to␈αmean␈α" is defined to be the macro ...".␈α Then␈α
a␈αsimple␈αmacro␈αdefinition␈α
of␈α␈↓αplus␈↓
␈↓ ↓H␈↓might be:
␈↓ ↓H␈↓α␈↓ αXplus <␈↓βm␈↓α= λ[[l]␈↓ ∧_[eq[length[l];3] → concat[*PLUS;rest[l]]
␈↓ ↓H␈↓α␈↓ αX␈↓ ∧_ ␈↓
t␈↓α → list[*PLUS;second[l];concat[PLUS;rest[rest[l]]]]]]
␈↓ ↓H␈↓Thus␈αa␈α
call␈α␈↓α(PLUS␈α3␈α
4␈α5)␈↓␈αwould␈α
bind␈α␈↓αl␈↓␈αto␈α
␈↓α(PLUS␈α3␈α4␈α
5)␈↓␈αand␈αthe␈α
evaluation␈αof␈αthe␈α
body␈αwould
␈↓ ↓H␈↓result␈α
in␈α
␈↓α(*PLUS␈α
3␈α(PLUS␈α
4␈α
5))␈↓.␈α
Evaluation␈αof␈α
this␈α
expression␈α
would␈αresult␈α
in␈α
another␈α
call␈αon␈α
the
␈↓ ↓H␈↓macro.␈α∂ This␈α∞time␈α∂␈↓αl␈↓␈α∞would␈α∂be␈α∂bound␈α∞to␈α∂␈↓α(PLUS␈α∞4␈α∂5)␈↓.␈α∂Now␈α∞␈↓αeq[length[l];3]␈↓␈α∂␈↓↓is␈↓␈α∞true␈α∂and␈α∂the␈α∞value
␈↓ ↓H␈↓returned␈α
is␈α
␈↓α(*PLUS␈α
4␈α
5)␈↓.␈α∞ This␈α
will␈α
be␈α
evaluated,␈α
giving␈α∞␈↓α9␈↓;␈α
finally␈α
the␈α
outermost␈α
call␈α∞on␈α
␈↓α*PLUS␈↓
␈↓ ↓H␈↓has all its arguments evaluated, and we get the final answer, ␈↓α12␈↓.
␈↓ ↓H␈↓A more general macro expander can be described as:
␈↓ ↓H␈↓αexpand <= λ[[fn;l]␈↓ β8[null[rest[l]] → l;
␈↓ ↓H␈↓α␈↓ β8 ␈↓
t␈↓α → list[fn; first[l]; expand[fn;rest[l]]]]]
␈↓ ↓H␈↓Then we can define ␈↓αplus␈↓ <␈↓βm␈↓α= λ[[l] expand[*PLUS;rest[l]]]␈↓.
␈↓ ↓H␈↓Likewise␈α⊂␈↓αappend␈α⊂<␈↓βm␈↓α=␈α⊂λ[[l]␈α⊂expand[*APPEND;rest[l]]]␈↓␈α⊃where␈α⊂␈↓α*append␈↓␈α⊂is␈α⊂the␈α⊂binary␈α⊃version␈α⊂of
␈↓ ↓H␈↓␈↓αappend␈↓.
␈↓ ↓H␈↓Since␈α
the␈α
body␈α
of␈α
a␈α
macro␈α
has␈α
available␈αall␈α
of␈α
the␈α
evaluation␈α
mechanism␈α
of␈α
LISP,␈α
and␈α
since␈αthe
␈↓ ↓H␈↓program␈αstructure␈αof␈αLISP␈αis␈αalso␈αthe␈αdata␈αstructure,␈αwe␈αcan␈αperform␈αarbitrary␈αcomputations␈αinside
␈↓ ↓H␈↓the expansion of the macro.
␈↓ ↓H␈↓The␈α
idea␈α
of␈α
macro␈α
processing␈αis␈α
not␈α
recent.␈α
Some␈α
of␈αthe␈α
earliest␈α
assemblers␈α
had␈α
extensive␈αmacro
␈↓ ↓H␈↓facilities.␈α∞ Lately␈α∞macros␈α
have␈α∞been␈α∞used␈α∞as␈α
a␈α∞means␈α∞of␈α
extending␈α∞so-called␈α∞high␈α∞level␈α
languages.
␈↓ ↓H␈↓One␈αof␈α
the␈αmost␈α
simple␈αkinds␈αof␈α
macros␈αis␈α
␈↓↓textual␈αsubstitution␈↓.␈α
That␈αis,␈αwhen␈α
a␈αuse␈α
of␈αa␈αmacro␈α
is
␈↓ ↓H␈↓detected␈α∞we␈α∂simply␈α∞replace␈α∂the␈α∞call␈α∞by␈α∂its␈α∞body.␈α∂ A␈α∞slightly␈α∞more␈α∂sophisticated␈α∞application␈α∂is␈α∞the
␈↓ ↓H␈↓␈↓↓syntax␈αmacro␈↓.␈α
Everytime␈αwe␈α
come␈αacross␈α
an␈αapplication␈α
of␈αa␈α
syntax␈αmacro␈α
the␈αexpander␈α
processes
␈↓ ↓H␈↓it␈α
as␈αif␈α
it␈αhad␈α
never␈αbeen␈α
seen␈α
before␈αeven␈α
though␈αmuch␈α
of␈αthe␈α
expansion␈αis␈α
repetitious.␈α
That␈αis,
␈↓ ↓H␈↓syntax macros have no memory.
␈↓ ↓H␈↓␈↓↓computational␈αmacros␈↓␈α
are␈αan␈α
attempt␈αto␈α
reduce␈αsome␈α
of␈αthis␈α
repetition.␈α In␈α
this␈αscheme␈α
a␈αcertain
␈↓ ↓H␈↓amount␈α⊂of␈α⊃processing␈α⊂is␈α⊃done␈α⊂at␈α⊃the␈α⊂time␈α⊃the␈α⊂macro␈α⊃is␈α⊂␈↓↓defined␈↓.␈α⊃For␈α⊂example␈α⊃a␈α⊂computational
␈↓ ↓H␈↓subtree␈α
reflecting␈αthe␈α
body␈αof␈α
the␈αmacro␈α
might␈αbe␈α
formed.␈α Then␈α
whenever␈αthe␈α
macro␈αis␈α
␈↓↓used␈↓␈αwe
␈↓ ↓H␈↓can␈α∞simply␈α∞make␈α∞a␈α
copy␈α∞of␈α∞this␈α∞subtree␈α
and␈α∞"glue"␈α∞this␈α∞subtree␈α
into␈α∞the␈α∞parse-tree␈α∞which␈α∞we␈α
are
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 94␈↓ A similar device, called "meta composition", is used in [Bac 73].
␈↓ ↓H␈↓␈↓↓3.12␈↓ λ↔Special Forms and Macros 143␈↓
␈↓ ↓H␈↓building.␈α⊃ This␈α⊃computational␈α⊃subtree␈α⊃is␈α⊃commonly␈α⊃formed␈α⊃by␈α⊃passing␈α⊃the␈α⊃body␈α⊃of␈α∩the␈α⊃macro
␈↓ ↓H␈↓through␈αthe␈αcompiler␈α
in␈αa␈α"funny"␈αway.␈α
The␈αmain␈αproblem␈αwith␈α
the␈αcomputational␈αmacro␈α
is␈αthat
␈↓ ↓H␈↓there␈α∩are␈α∩many␈α∪desirable␈α∩macros␈α∩which␈α∪have␈α∩no␈α∩such␈α∩subtree,␈α∪or␈α∩there␈α∩is␈α∪other␈α∩information
␈↓ ↓H␈↓necessary␈αto␈αprocess␈αthe␈αmacro.␈α There␈αare␈αsolutions␈αto␈αthis␈αproblem,␈αone␈αof␈αwhich␈αclosely␈αparallels
␈↓ ↓H␈↓the␈α⊂abstract␈α⊂syntax␈α⊃ideas␈α⊂of␈α⊂McCarthy.␈α⊃ All␈α⊂of␈α⊂these␈α⊃styles␈α⊂of␈α⊂macros␈α⊃are␈α⊂subsets␈α⊂of␈α⊃the␈α⊂LISP
␈↓ ↓H␈↓macros.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I.␈α
What␈α
is␈α
the␈α
difference␈α
between␈αa␈α
special␈α
form␈α
and␈α
call-by-name␈α
evaluation?␈α
Can␈αcall-by-name␈α
be
␈↓ ↓H␈↓simulated in LISP without redefining ␈↓αeval␈↓?
␈↓ ↓H␈↓II.␈α␈↓αselect␈↓␈αis␈αa␈αspecial␈αform␈αto␈αbe␈αcalled␈αas:␈α␈↓αselect[q;q␈↓β1␈↓α;e␈↓β1␈↓α; ... ;q␈↓βn␈↓α;e␈↓βn␈↓α;e]␈↓␈αand␈αto␈αbe␈αevaluated␈αas␈αfollows:␈α␈↓αq␈↓
␈↓ ↓H␈↓is␈α
evaluated;␈α
the␈α
␈↓αq␈↓βi␈↓'s␈α
are␈α
evaluated␈α
from␈α
left␈α
to␈α∞right␈α
until␈α
one␈α
is␈α
found␈α
with␈α
the␈α
value␈α
of␈α∞␈↓αq␈↓.␈α
The
␈↓ ↓H␈↓value␈αof␈α␈↓αselect␈↓␈αis␈αthe␈αvalue␈αof␈αthe␈αcorresponding␈α␈↓αe␈↓βi␈↓.␈αIf␈αno␈αsuch␈α␈↓αq␈↓βi␈↓␈αis␈αfound␈αthe␈αvalue␈αof␈α␈↓αselect␈↓␈αis␈αthe
␈↓ ↓H␈↓value␈α
of␈α
␈↓αe␈↓.␈α
␈↓αselect␈↓␈α
is␈α
a␈α
precursor␈α
of␈α
the␈α
␈↓↓case␈α
statement␈↓;␈α
see␈α
page 179.␈α
Add␈α
a␈α
recognizer␈α
to␈α
␈↓αeval␈↓␈αto
␈↓ ↓H␈↓handle ␈↓αselect␈↓ and write a function to perform the evaluation of ␈↓αselect␈↓.
␈↓ ↓H␈↓III. Define ␈↓αlist␈↓ as a macro.
␈↓ ↓H␈↓IV. Extend the ␈↓αeval-apply␈↓ pair of Section 3.5 to handle macros.
␈↓ ↓H␈↓␈↓ ¬⊗␈↓↓3.13 Review and Reflection␈↓
␈↓ ↓H␈↓␈↓ ∧λ"I␈α∂think␈α∂that␈α∂it␈α⊂is␈α∂important␈α∂to␈α∂maintain␈α∂a␈α⊂view␈α∂of␈α∂the␈α∂field␈α⊂that␈α∂helps
␈↓ ↓H␈↓␈↓ ∧λminimize the distance between theoretical and practical work."
␈↓ ↓H␈↓␈↓ *Saul Amarel, [Ama 72]
␈↓ ↓H␈↓By␈α⊃way␈α⊂of␈α⊃review␈α⊃we␈α⊂sketch␈α⊃the␈α⊂basic␈α⊃LISP␈α⊃evaluator␈α⊂of␈α⊃Section 3.5:␈α⊂␈↓αeval␈↓␈α⊃plus␈α⊃the␈α⊂additional
␈↓ ↓H␈↓artifacts for ␈↓αlabel␈↓ and ␈↓αfunction␈↓.
␈↓ ↓H␈↓There␈αare␈αtwo␈αarguments␈αto␈α␈↓αeval␈↓:␈αa␈α␈↓↓form␈↓␈↓π 95␈↓,␈αthat␈αis,␈αan␈αexpression␈αwhich␈αcan␈αbe␈αevaluated;␈αand␈αan
␈↓ ↓H␈↓association␈α⊃list␈α⊂or␈α⊃␈↓↓symbol␈α⊂table␈↓.␈α⊃If␈α⊂the␈α⊃form␈α⊃is␈α⊂a␈α⊃constant,␈α⊂return␈α⊃that␈α⊂form.␈α⊃If␈α⊂the␈α⊃form␈α⊃is␈α⊂a
␈↓ ↓H␈↓variable,␈α
find␈α
the␈α
value␈α
of␈α
the␈α
variable␈α
in␈α
the␈α
current␈α
environment.␈α
If␈α
the␈α
form␈α
is␈α∞a␈α
conditional
␈↓ ↓H␈↓expression, then evaluate it according to the semantics of conditional expressions.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 95␈↓␈α⊃Throughout␈α⊃this␈α⊃section␈α∩we␈α⊃will␈α⊃say␈α⊃"form",␈α∩"variable",␈α⊃"λ-expression",␈α⊃etc.␈α⊃ rather␈α∩than␈α⊃"a
␈↓ ↓H␈↓representation␈α∪of␈α∪a"␈α∩...␈α∪"form",␈α∪"variable",␈α∩"λ-expression",␈α∪etc.␈α∪No␈α∩confusion␈α∪should␈α∪result,␈α∩but
␈↓ ↓H␈↓remember that we ␈↓↓are␈↓ speaking imprecisely.
␈↓ ↓H␈↓␈↓↓144 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓The␈α
form␈α
might␈α
also␈α
be␈α
a␈α
functional␈αargument.␈α
In␈α
this␈α
case␈α
evaluation␈α
consists␈α
of␈α
associating␈αthe
␈↓ ↓H␈↓current␈αenvironment␈αwith␈αthe␈αfunction␈αand␈αreturning␈αthat␈αconstruct␈αas␈αvalue;␈αin␈αLISP␈αthis␈αis␈αdone
␈↓ ↓H␈↓with␈α
the␈α
␈↓αfunarg␈↓␈α∞device.␈α
Any␈α
other␈α
form␈α∞seen␈α
by␈α
␈↓αeval␈↓␈α∞is␈α
assumed␈α
to␈α
be␈α∞an␈α
application,␈α
that␈α∞is,␈α
a
␈↓ ↓H␈↓function␈αfollowed␈αby␈αarguments.␈α The␈α
arguments␈αare␈αevaluated␈αfrom␈αleft-to-right␈αand␈α
the␈αfunction
␈↓ ↓H␈↓is then applied to these arguments.
␈↓ ↓H␈↓The␈α∞part␈α
of␈α∞the␈α∞evaluator␈α
which␈α∞handles␈α∞function␈α
application␈α∞is␈α∞called␈α
␈↓αapply␈↓.␈α∞ ␈↓αapply␈↓␈α∞takes␈α
three
␈↓ ↓H␈↓arguments:␈α
a␈α
LISP␈α
function,␈α
a␈α
list␈α
of␈α∞evaluated␈α
arguments,␈α
and␈α
a␈α
symbol␈α
table.␈α
If␈α
the␈α∞function␈α
is
␈↓ ↓H␈↓one␈α∂of␈α∂the␈α∂five␈α∞LISP␈α∂primitives␈α∂then␈α∂the␈α∞appropriate␈α∂action␈α∂is␈α∂carried␈α∞out.␈α∂If␈α∂the␈α∂function␈α∂is␈α∞a
␈↓ ↓H␈↓λ-expression␈α∂then␈α∂bind␈α⊂the␈α∂formal␈α∂parameters␈α∂(the␈α⊂λ-variables)␈α∂to␈α∂the␈α∂evaluated␈α⊂arguments␈α∂and
␈↓ ↓H␈↓evaluate␈αthe␈αbody␈αof␈αthe␈αfunction.␈αThe␈αfunction␈αmight␈αalso␈αbe␈αthe␈αresult␈αof␈αa␈αfunctional␈αargument
␈↓ ↓H␈↓binding;␈α
in␈α
this␈α∞case␈α
apply␈α
the␈α
function␈α∞to␈α
the␈α
arguments␈α
and␈α∞use␈α
the␈α
saved␈α∞environment,␈α
rather
␈↓ ↓H␈↓than␈α
the␈α
given␈α
environment,␈α
to␈α
search␈α
for␈α
non-local␈α
bindings.␈α
If␈α
we␈α
are␈α
applying␈α
the␈α␈↓αlabel␈↓␈α
operator,
␈↓ ↓H␈↓recalling␈α⊃page 131,␈α∩we␈α⊃build␈α⊃a␈α∩␈↓αfunarg␈↓-triple␈α⊃and␈α⊃new␈α∩environment␈α⊃such␈α⊃that␈α∩the␈α⊃environment
␈↓ ↓H␈↓bound␈αin␈α
the␈αtriple␈αis␈α
the␈αnew␈αenvironment.␈α
We␈αthen␈αapply␈α
the␈αfunction␈αto␈α
the␈αarguments␈α
in␈αthis
␈↓ ↓H␈↓new environment.
␈↓ ↓H␈↓If␈αthe␈α
function␈αhas␈αa␈α
name␈αwe␈αlook␈α
up␈αthat␈αname␈α
in␈αthe␈αcurrent␈α
environment.␈α Currently␈αwe␈α
expect
␈↓ ↓H␈↓that␈α∂value␈α∂to␈α∂be␈α∂a␈α∂λ-expression,␈α∂which␈α∂is␈α∂then␈α∂applied.␈α∂However,␈α∂since␈α∂function␈α∂names␈α∂are␈α∞just
␈↓ ↓H␈↓variables,␈αthere␈αis␈αno␈αreason␈αthat␈αthe␈αvalue␈αof␈αa␈αfunction␈αname␈αcould␈αnot␈αbe␈αa␈αsimple␈αvalue,␈αsay␈αan
␈↓ ↓H␈↓atom,␈α∞and␈α∞␈↓↓that␈↓␈α∞value␈α∞can␈α∞be␈α∞applied␈α∂to␈α∞the␈α∞arguments.␈α∞ Examination␈α∞of␈α∞␈↓αapply␈↓␈α∞on␈α∂page 104␈α∞will
␈↓ ↓H␈↓show␈α
that␈α
␈↓αapply[X; ((A B)) ; ((X . CAR) ... )]␈↓␈α␈↓↓will␈↓␈α
be␈α
handled␈αcorrectly.␈α
The␈α
natural␈α
extension␈αof
␈↓ ↓H␈↓this␈α∪idea␈α∩is␈α∪to␈α∩allow␈α∪a␈α∩␈↓↓computed␈α∪function␈↓.␈α∩That␈α∪is,␈α∩if␈α∪the␈α∩function␈α∪passed␈α∩to␈α∪␈↓αapply␈↓␈α∪is␈α∩not
␈↓ ↓H␈↓recognized␈α∂as␈α∂one␈α∂of␈α∂the␈α∂preceding␈α∂cases,␈α∂then␈α∂continue␈α∂to␈α∂evaluate␈α∂the␈α∂function-part␈α∂until␈α⊂it␈α∂is
␈↓ ↓H␈↓recognized.
␈↓ ↓H␈↓We will allow such forms as:
␈↓ ↓H␈↓α␈↓ ∧β((CAR (QUOTE (CAR (A . B)))) (QUOTE (A . B)))
␈↓ ↓H␈↓The addition of computed functions modifies ␈↓αapply␈↓ (page 104) slightly:
␈↓ ↓H␈↓αapply <= λ[[fn;args;environ]␈↓ ∧H[iscar[fn] → car[arg␈↓β1␈↓α[args]];
␈↓ ↓H␈↓α␈↓ ∧H iscons[fn] → cons[arg␈↓β1␈↓α[args];arg␈↓β2␈↓α[args]];
␈↓ ↓H␈↓α␈↓ ∧H ... ...
␈↓ ↓H␈↓α␈↓ ∧H islambda[fn] → eval[␈↓ εXbody[fn];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬X␈↓ εXpairlis[vars[fn];args;environ]];
␈↓ ↓H␈↓α␈↓ ∧H ␈↓
t␈↓α → apply[␈↓ ¬Xeval[fn;environ];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬Xargs;
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬Xenviron] ]]
␈↓ ↓H␈↓The␈α∂subset␈α⊂of␈α∂LISP␈α∂which␈α⊂is␈α∂captured␈α⊂by␈α∂this␈α∂evaluator␈α⊂is␈α∂a␈α∂strong␈α⊂and␈α∂useful␈α⊂language␈α∂even
␈↓ ↓H␈↓though␈α⊂it␈α⊂lacks␈α⊂several␈α⊂of␈α⊂the␈α⊂more␈α⊂common␈α⊂programming␈α⊂language␈α⊂features␈↓π 96␈↓.␈α⊂This␈α⊂subset␈α⊂is
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 96␈↓␈α
It␈α
is␈α∞"strong",␈α
both␈α
practically␈α
and␈α∞theoretically.␈α
It␈α
is␈α
sufficiently␈α∞powerful␈α
to␈α
be␈α∞"universal"␈α
in
␈↓ ↓H␈↓the␈α⊃sense␈α⊃that␈α⊂all␈α⊃computable␈α⊃functions␈α⊃are␈α⊂representable␈α⊃in␈α⊃LISP.␈α⊂In␈α⊃fact␈α⊃the␈α⊃␈↓αeval-apply␈↓␈α⊂pair
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 145␈↓
␈↓ ↓H␈↓called␈αthe␈α␈↓↓applicative␈αsubset␈αof␈αLISP␈↓,␈αsince␈αits␈αcomputational␈αability␈αis␈αbased␈αon␈αthe␈αmathematical
␈↓ ↓H␈↓idea␈α∩of␈α∩function␈α∪application.␈α∩We␈α∩have␈α∪persistently␈α∩referred␈α∩to␈α∪our␈α∩LISP␈α∩procedures␈α∪as␈α∩LISP
␈↓ ↓H␈↓functions,␈α∃even␈α∃though␈α∃we␈α∀have␈α∃seen␈α∃some␈α∃differences␈α∀between␈α∃the␈α∃concept␈α∃of␈α∃function␈α∀in
␈↓ ↓H␈↓mathematics␈αand␈αthe␈αconcepts␈αof␈αprocedure␈αin␈αLISP.␈αIt␈αis␈αthe␈αmathematical␈αidea␈αof␈αfunction␈αwhich
␈↓ ↓H␈↓the␈α
procedures␈α
of␈α
an␈α
applicative␈α
language␈α
are␈α
trying␈α
to␈α
capture.␈α
Regardless␈α
of␈α
differences␈αin␈α
syntax
␈↓ ↓H␈↓and␈α⊂evaluation␈α∂schemes,␈α⊂the␈α∂dominant␈α⊂characteristic␈α∂of␈α⊂an␈α∂applicative␈α⊂language␈α∂is␈α⊂that␈α⊂a␈α∂given
␈↓ ↓H␈↓"function"␈α∪applied␈α∪to␈α∪a␈α∪given␈α∪set␈α∪of␈α∪arguments␈α∪␈↓↓always␈↓␈α∪produced␈α∪the␈α∪same␈α∪result:␈α∪either␈α∪the
␈↓ ↓H␈↓computation␈α∩produces␈α∩an␈α∩error,␈α∩or␈α∩it␈α∩doesn't␈α∩terminate,␈α∩or␈α∩it␈α∩produces␈α∩a␈α∩specific␈α∪value.␈α∩ The
␈↓ ↓H␈↓applicative␈α∂subset␈α∞of␈α∂LISP␈α∂uses␈α∞dynamic␈α∂binding␈α∞and␈α∂therefore␈α∂the␈α∞occurrence␈α∂of␈α∂free␈α∞variables
␈↓ ↓H␈↓calls␈α
the␈αenvironment␈α
into␈αplay.␈α
But␈αstill,␈α
we␈αhave␈α
no␈αway␈α
to␈αdestructively␈α
change␈αthe␈α
environment.
␈↓ ↓H␈↓Constructs␈α
which␈α∞do␈α
have␈α
such␈α∞an␈α
ability␈α∞are␈α
said␈α
to␈α∞have␈α
␈↓↓side-effects␈↓␈α
and␈α∞are␈α
discussed␈α∞in␈α
the
␈↓ ↓H␈↓next chapter.
␈↓ ↓H␈↓LISP␈α
was␈αthe␈α
first␈αlanguage␈α
to␈αexploit␈α
procedures␈αas␈α
objects␈αof␈α
the␈αlanguage.␈α
The␈αidea␈α
has␈αbeen
␈↓ ↓H␈↓generalized␈α
substantially␈αin␈α
the␈αintervening␈α
years.␈αA␈α
concise␈αstatement␈α
of␈αthe␈α
more␈αgeneral␈α
principle
␈↓ ↓H␈↓appears in [Pop 68a].
␈↓ ↓H␈↓␈↓ αh"...This␈α
brings␈α
us␈α
to␈α
the␈α
subject␈α
of␈α
items.␈α
Anything␈α
which␈α
can␈α
be␈α
the␈α
value
␈↓ ↓H␈↓␈↓ αhof a variable is an item. ␈↓αAll items have certain fundamental rights.␈↓
␈↓ ↓H␈↓␈↓ β_1. All items can be the actual parameters of functions
␈↓ ↓H␈↓␈↓ β_2. All items can be returned as results of functions
␈↓ ↓H␈↓␈↓ β_3. All items can be the subject of assignment statements␈↓π 97␈↓
␈↓ ↓H␈↓␈↓ β_4. All items can be tested for equality.
␈↓ ↓H␈↓␈↓ αh..."
␈↓ ↓H␈↓LISP␈α
performs␈αwell␈α
on␈α
the␈αfirst␈α
two␈αprinciples,␈α
allowing␈α
LISP␈αfunctions␈α
to␈α
be␈αthe␈α
arguments␈αas␈α
well
␈↓ ↓H␈↓as␈α
the␈αresults␈α
of␈α
functions.␈αThe␈α
fourth␈α
principle␈αis␈α
more␈α
difficult;␈αthat␈α
is,␈α
test␈αfor␈α
the␈α
equality␈αof␈α
two
␈↓ ↓H␈↓LISP␈α⊂functions.␈α⊃ In␈α⊂can␈α⊃be␈α⊂shown␈α⊃([Rog 67])␈α⊂that␈α⊂no␈α⊃algorithm␈α⊂can␈α⊃be␈α⊂constructed␈α⊃which␈α⊂will
␈↓ ↓H␈↓perform␈α
such␈α
a␈α
test␈α
for␈α
arbitrary␈αfunctions.␈α
However␈α
in␈α
more␈α
selective␈α
settings,␈α
program␈αequality
␈↓ ↓H␈↓can be established, both theoretically ([Man 74]), and practically ([Boy 75], [Dar 73], [Car 76]).
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓represents␈α⊃a␈α⊃"universal␈α⊂function",␈α⊃capable␈α⊃of␈α⊂simulating␈α⊃the␈α⊃behavior␈α⊂of␈α⊃any␈α⊃other␈α⊂computable
␈↓ ↓H␈↓function.␈α⊂The␈α⊂usual␈α⊂arguments␈α⊂about␈α⊃the␈α⊂halting␈α⊂problem ([Rog 67]␈α⊂and␈α⊂page 167)␈α⊃and␈α⊂related
␈↓ ↓H␈↓matters␈α∃are␈α∃easily␈α∃expressed␈α∃and␈α∃proved␈α∀in␈α∃this␈α∃LISP.␈α∃Indeed,␈α∃the␈α∃original␈α∃motivation␈α∀for
␈↓ ↓H␈↓introducing␈α⊂the␈α∂M-to-S␈α⊂expression␈α⊂mapping␈α∂was␈α⊂to␈α∂express␈α⊂the␈α⊂language␈α∂constructs␈α⊂in␈α⊂the␈α∂data
␈↓ ↓H␈↓domain␈α→so␈α→that␈α→universality␈α→could␈α~be␈α→demonstrated.␈α→ "S-expression LISP"␈α→was␈α→used␈α~as␈α→a
␈↓ ↓H␈↓programming␈α
language␈α
only␈αas␈α
an␈α
afterthought.␈α It␈α
was␈α
S. Russell␈αwho␈α
convinced␈α
Mc Carthy␈αthat
␈↓ ↓H␈↓the theoretical device represented in ␈↓αeval␈↓ and ␈↓αapply␈↓ could in fact be programmed on the IBM704.
␈↓ ↓H␈↓␈↓π 97␈↓ This issue will be postponed until Chapter 4.
␈↓ ↓H␈↓␈↓↓146 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓The␈α
language,␈α
POP-2 ([Pop 68]),␈α
has␈α
also␈α
generalized␈αthe␈α
notion␈α
of␈α
function␈α
application␈α
in␈αa␈α
slight,
␈↓ ↓H␈↓but significant, way. The generalization is called ␈↓↓partial application␈↓. Given a function
␈↓ ↓H␈↓α␈↓ ¬Mf <= λ[[x␈↓β1␈↓α; ... ;x␈↓βn␈↓α] ␈↓λx␈↓α]␈↓,
␈↓ ↓H␈↓we␈αcompute␈αa␈αnew␈αfunction␈αof␈α␈↓αn-m␈↓␈αarguments␈αby␈αapplying␈α␈↓αf␈↓␈αto␈α␈↓αm␈↓␈αarguments␈αand␈αobtain␈αa␈αfunction
␈↓ ↓H␈↓of the remaining arguments ␈↓αx␈↓βm+1␈↓ through ␈↓αx␈↓βn␈↓:
␈↓ ↓H␈↓α␈↓ ¬ λ[[x␈↓βm+1␈↓α; ...x␈↓βn␈↓α] ␈↓λx'␈↓α] = f[t␈↓β1␈↓α; ...; t␈↓βm␈↓α]
␈↓ ↓H␈↓where ␈↓λx'␈↓ results from ␈↓λx␈↓ by binding ␈↓αx␈↓β1␈↓ through ␈↓αx␈↓βm␈↓ to ␈↓αt␈↓β1␈↓ through ␈↓αt␈↓βm␈↓ respectively␈↓π 98␈↓
␈↓ ↓H␈↓Further generalizations of partial application are imaginable ([Sta 74]).
␈↓ ↓H␈↓We␈α∂have␈α∂pointed␈α∂out␈α∂several␈α∂"procedural"␈α∂differences.␈α∂Our␈α∂treatment␈α∂of␈α⊂conditional␈α∂expressions
␈↓ ↓H␈↓differs␈αfrom␈αthe␈αusual␈αtreatment␈αof␈αfunction␈αapplication:␈αour␈αstandard␈αrule␈αfor␈αfunction␈αapplication
␈↓ ↓H␈↓is␈α"call by value"␈αwhich␈αrequires␈αthe␈αevaluation␈αof␈αall␈αarguments␈αbefore␈αcalling␈αthe␈α
LISP␈αfunction;
␈↓ ↓H␈↓only␈αsome␈α
of␈αthe␈α
arguments␈αto␈α
a␈αconditional␈α
expression␈αare␈α
evaluated.␈αNote␈α
that␈αthe␈αwhole␈α
question
␈↓ ↓H␈↓of␈α"evaluation␈αof␈αarguments"␈αis␈αa␈αprocedural␈αone;␈αarguments␈αto␈αfunctions␈αaren't␈α"evaluated"␈αor␈α"not
␈↓ ↓H␈↓evaluated", they just "are".
␈↓ ↓H␈↓We␈α∞have␈α∞seen␈α∞different␈α∂algorithms␈α∞computing␈α∞the␈α∞same␈α∂function;␈α∞for␈α∞example␈α∞␈↓αfact␈↓␈α∂(page 45␈α∞and
␈↓ ↓H␈↓page 135)␈α∞and␈α
␈↓αfact␈↓β1␈↓ (page 45)␈α∞all␈α
compute␈α∞the␈α
factorial␈α∞function.␈α
If␈α∞there␈α
are␈α∞different␈α
algorithms
␈↓ ↓H␈↓for␈α∃computing␈α∃factorial,␈α∃then␈α∃there␈α∃are␈α⊗different␈α∃alorithms␈α∃for␈α∃computing␈α∃the␈α∃value␈α⊗of␈α∃an
␈↓ ↓H␈↓expression,␈α
and␈α␈↓αeval␈↓␈α
is␈α
just␈αone␈α
such␈α
algorithm.␈α Just␈α
as␈α
the␈αessence␈α
of␈α
␈↓αfact␈↓␈αand␈α
␈↓αfact␈↓β1␈↓␈α
is␈αthe␈α
factorial
␈↓ ↓H␈↓function,␈α∂we␈α∂should␈α∂capture␈α⊂the␈α∂essence␈α∂expressed␈α∂in␈α⊂␈↓αeval␈↓.␈α∂ Put␈α∂another␈α∂way,␈α⊂when␈α∂applications
␈↓ ↓H␈↓programmers␈α
use␈α
␈↓αsqrt␈↓␈α
or␈α
␈↓εp␈↓␈αthey␈α
have␈α
a␈α
specific␈α
mathematical␈αfunction␈α
or␈α
constant␈α
in␈α
mind.␈α The
␈↓ ↓H␈↓implementation␈α∃of␈α∃the␈α∀language␈α∃supplies␈α∃approximations␈α∀to␈α∃these␈α∃mathematical␈α∃entities,␈α∀and
␈↓ ↓H␈↓assuming␈αthe␈αcomputations␈αstay␈αwithin␈αthe␈αnumerical␈αranges␈αof␈αthe␈αmachine,␈αthe␈αprogrammers␈αare
␈↓ ↓H␈↓free␈α∃to␈α∃interpret␈α∃any␈α∀output␈α∃as␈α∃that␈α∃which␈α∀the␈α∃mathematical␈α∃entities␈α∃would␈α∃produce.␈α∀More
␈↓ ↓H␈↓importantly␈αthe␈αprogrammers␈αhave␈αplaced␈αspecific␈αinterpretations␈αor␈αmeanings␈αon␈αsymbols.␈αWe␈αare
␈↓ ↓H␈↓interested␈α⊂in␈α⊂doing␈α∂the␈α⊂same␈α⊂thing␈α⊂only␈α∂we␈α⊂wish␈α⊂to␈α⊂produce␈α∂a␈α⊂␈↓↓freer␈↓␈α⊂interpretation,␈α⊂which␈α∂only
␈↓ ↓H␈↓mirrors␈αthe␈αessential␈αingredients␈αof␈αthe␈αlanguage␈αconstructs.␈αThat␈αis,␈α␈↓αsqrt␈↓␈αrepresents␈αa␈α␈↓↓function␈↓␈αand
␈↓ ↓H␈↓␈↓εp␈↓␈αrepresents␈αa␈α␈↓↓constant␈↓.␈α The␈α␈↓αeval-apply␈↓␈αpair␈αgives␈αone␈αinterpretation␈αto␈αthe␈αmeaning␈αof␈αfunctions
␈↓ ↓H␈↓and␈αconstants,␈αbut␈αthere␈αare␈αdifferent␈αinterpretations␈αand␈αthere␈αare␈αdifferent␈α␈↓αeval-apply␈↓␈αpairs.␈α The
␈↓ ↓H␈↓remainder of this section will resolve some of the tension between function and procedure.
␈↓ ↓H␈↓What␈α
does␈α
this␈α
discussion␈α
have␈α
to␈α
do␈α
with␈α
programming␈α
languages?␈α
Clearly␈α
the␈α
order␈αof␈α
evaluation
␈↓ ↓H␈↓or␈α
reduction␈αis␈α
directly␈α
applicable.␈αOur␈α
study␈αwill␈α
also␈α
give␈αinsights␈α
into␈αthe␈α
problem␈α
of␈αlanguage
␈↓ ↓H␈↓specification.␈α Do␈α
we␈αsay␈αthat␈α
the␈αlanguage␈αspecification␈α
consists␈αof␈αa␈α
syntactic␈αcomponent␈αand␈α
some
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 98␈↓ POP-2 actually binds the ␈↓↓last␈↓ ␈↓αm␈↓ arguments.
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 147␈↓
␈↓ ↓H␈↓description␈α∪of␈α∪the␈α∪evaluation␈α∪of␈α∪constructs␈α∪in␈α∪that␈α∪language?␈α∪ Or␈α∪do␈α∪we␈α∪say␈α∪that␈α∀these␈α∪two
␈↓ ↓H␈↓components,␈αsyntax␈αand␈αa␈αmachine,␈αare␈αmerely␈αdevices␈αfor␈αdescribing␈αor␈αformalizing␈αnotions␈αabout
␈↓ ↓H␈↓some␈α∞abstract␈α
domain␈α∞of␈α
discourse?␈α∞ A␈α∞related␈α
question␈α∞for␈α
programmers␈α∞and␈α∞language␈α
designers
␈↓ ↓H␈↓involves␈αthe␈αideas␈αof␈αcorrectness␈αand␈αequivalence␈αof␈αprograms.␈αHow␈αdo␈αwe␈αknow␈αwhen␈αa␈αprogram
␈↓ ↓H␈↓is␈α
correct?␈α This␈α
requires␈α
some␈αnotion␈α
of␈α
a␈αstandard␈α
against␈α
which␈αto␈α
test␈α
our␈αimplementations␈↓π 99␈↓.␈α
If
␈↓ ↓H␈↓our␈α
algorithms␈αreally␈α
are␈α
reflections␈αof␈α
functional␈αproperties,␈α
then␈α
we␈αshould␈α
develop␈α
methods␈αfor
␈↓ ↓H␈↓verifying␈α
that␈α
those␈α
properties␈αare␈α
expressed␈α
in␈α
our␈α
algorithms.␈αAgainst␈α
this␈α
we␈α
must␈α
balance␈αthe
␈↓ ↓H␈↓realization␈αthat␈αmany␈αprograms␈αdon't␈αfit␈αneatly␈αinto␈αthis␈αmathematical␈αframework.␈αMany␈αprograms
␈↓ ↓H␈↓are␈α∀best␈α∀characterized␈α∀as␈α∪themselves.␈α∀In␈α∀this␈α∀case␈α∀we␈α∪should␈α∀then␈α∀be␈α∀interested␈α∀in␈α∪verfying
␈↓ ↓H␈↓equivalence␈α⊗of␈α⊗programs.␈α↔If␈α⊗we␈α⊗develop␈α↔a␈α⊗new␈α⊗algorithm␈α↔we␈α⊗have␈α⊗some␈α↔responsibility␈α⊗to
␈↓ ↓H␈↓demonstrate that the algorithms are equivalent in very well defined ways␈↓π 100␈↓.
␈↓ ↓H␈↓The␈αstudy␈αof␈α
formal␈αsystems␈αin␈αmathematical␈α
logic␈αoffers␈αinsight.␈α There,␈α
we␈αare␈αpresented␈α
with␈αa
␈↓ ↓H␈↓syntax␈αand␈αa␈α
system␈αof␈αaxioms␈α
and␈αrules␈αof␈αinference.␈α
Most␈αusually␈αwe␈α
are␈αalso␈αoffered␈α
a␈α"model
␈↓ ↓H␈↓theory"␈α⊃which␈α∩gives␈α⊃us␈α⊃interpretations␈α∩for␈α⊃the␈α⊃objects␈α∩of␈α⊃the␈α⊃formal␈α∩system;␈α⊃the␈α∩model␈α⊃theory
␈↓ ↓H␈↓supplies␈α⊂additional␈α∂means␈α⊂of␈α∂giving␈α⊂convincing␈α∂arguments␈α⊂for␈α∂the␈α⊂validity␈α∂of␈α⊂statements␈α⊂in␈α∂the
␈↓ ↓H␈↓formal␈α↔system.␈α↔ The␈α↔arguments␈α_made␈α↔within␈α↔the␈α↔formal␈α_system␈α↔are␈α↔couched␈α↔in␈α_terms␈α↔of
␈↓ ↓H␈↓"provability"␈αwhereas␈α
arguments␈αof␈α
the␈αmodel␈α
theory␈αare␈α
given␈αin␈α
terms␈αof␈α
"truth".␈αFor␈αa␈α
discussion
␈↓ ↓H␈↓of formal systems and model theory see [Men 64].
␈↓ ↓H␈↓C. W. Morris ([Mor 55]) isolated three perspectives on language, syntax, pragmatics, and semantics.
␈↓ ↓H␈↓␈↓↓Syntax␈↓:␈α⊂The␈α⊂synthesis␈α∂and␈α⊂analysis␈α⊂of␈α∂sentences␈α⊂in␈α⊂a␈α∂language.␈α⊂This␈α⊂area␈α∂is␈α⊂well␈α⊂cultivated␈α∂in
␈↓ ↓H␈↓␈↓ αHprogramming language specification.
␈↓ ↓H␈↓␈↓↓Pragmatics␈↓:␈αThe␈αrelation␈αbetween␈αthe␈αlanguage␈α
and␈αits␈αuser.␈αEvaluators,␈αlike␈α␈↓αtgmoaf,␈α
tgmoafr␈↓␈αand
␈↓ ↓H␈↓␈↓ αx␈↓αeval␈↓,␈αcome␈αunder␈αthe␈αheading␈αof␈αpragmatics.␈α Pragmatics␈αare␈αmore␈αcommonly␈αreferred
␈↓ ↓H␈↓␈↓ αxto as operational semantics in discussions of programming languages.
␈↓ ↓H␈↓␈↓↓Semantics␈↓:␈α∞The␈α∞relation␈α∞between␈α∞constructs␈α∞of␈α∞the␈α∞language␈α∞and␈α∞the␈α∞abstract␈α∞objects␈α∂which␈α∞they
␈↓ ↓H␈↓␈↓ αhdenote. This subdivision is commonly referred to as denotational semantics.
␈↓ ↓H␈↓Put␈α∂differently,␈α∞syntax␈α∂describes␈α∞appearance,␈α∂pragmatics␈α∞describes␈α∂implementation,␈α∂and␈α∞semantics
␈↓ ↓H␈↓describes␈α∂meaning␈↓π 101␈↓.␈α∂ Though␈α∂there␈α∂is␈α∂a␈α∂strong␈α∂concensus␈α∂on␈α∂the␈α∂syntactic␈α∂tools␈α∂for␈α∞specifying
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 99␈↓␈α"Unless␈αthere␈αis␈αa␈αprior␈α
mathematical␈αdefinition␈αof␈αa␈αlanguage␈αat␈α
hand,␈αwho␈αis␈αto␈αsay␈αwhether␈α
a
␈↓ ↓H␈↓proposed implementation is ␈↓↓correct␈↓?" [Sco 72].
␈↓ ↓H␈↓␈↓π 100␈↓␈α∂Current␈α∂theory␈α∂is␈α⊂inadequate␈α∂for␈α∂dealing␈α∂with␈α⊂many␈α∂real␈α∂programming␈α∂tasks.␈α⊂However␈α∂the
␈↓ ↓H␈↓realization␈α
that␈α
one␈α
has␈α∞a␈α
responsibility␈α
to␈α
consider␈α
the␈α∞questions,␈α
␈↓↓even␈α
informally␈↓,␈α
is␈α∞a␈α
sobering
␈↓ ↓H␈↓one which more programmers should experience.
␈↓ ↓H␈↓␈↓π 101␈↓␈α∩This␈α⊃division␈α∩of␈α⊃language␈α∩reflects␈α⊃an␈α∩interesting␈α⊃parallel␈α∩between␈α⊃mathematical␈α∩logic␈α⊃and
␈↓ ↓H␈↓programming␈α∩languages:␈α⊃in␈α∩mathematical␈α⊃logic␈α∩we␈α⊃have␈α∩deduction,␈α⊃computation,␈α∩and␈α∩truth;␈α⊃in
␈↓ ↓H␈↓programming␈α∀language␈α∀specification␈α∃we␈α∀have␈α∀three␈α∃analogous␈α∀schools␈α∀of␈α∃thought:␈α∀axiomatic,
␈↓ ↓H␈↓␈↓↓148 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓languages␈↓π 102␈↓,␈α∩there␈α∩is␈α∩no␈α∩concensus␈α∩on␈α∩adequate␈α∩pragmatics␈α∩and␈α∩even␈α∩less␈α∩agreement␈α∩on␈α⊃the
␈↓ ↓H␈↓adequancy␈α
of␈α
semantic␈α
descriptions.␈α We␈α
will␈α
first␈α
outline␈αthe␈α
pragmatics␈α
questions␈α
and␈αthen␈α
discuss
␈↓ ↓H␈↓a␈α⊂bit␈α⊂more␈α⊂of␈α⊂the␈α⊂semantics␈α⊂issues.␈α⊂ In␈α⊂this␈α⊂discussion␈α⊂we␈α⊂will␈α⊂use␈α⊂the␈α⊂language␈α⊂distinctions␈α⊂of
␈↓ ↓H␈↓Morris␈α∞even␈α
though␈α∞the␈α∞practice␈α
is␈α∞not␈α∞commonly␈α
followed␈α∞in␈α∞the␈α
literature.␈α∞ Typically,␈α∞syntax␈α
is
␈↓ ↓H␈↓studied␈α∞precisely␈α
and␈α∞semantics␈α
is␈α∞"everything␈α
else";␈α∞however␈α
the␈α∞distinction␈α∞between␈α
computation
␈↓ ↓H␈↓(pragmatics) and truth (semantics) is important and should not be muddled.
␈↓ ↓H␈↓One␈α∞thought␈α∞is␈α∞to␈α∞describe␈α∞the␈α∞pragmatics␈α∞of␈α
a␈α∞language␈α∞in␈α∞terms␈α∞of␈α∞the␈α∞process␈α∞of␈α
compilation.
␈↓ ↓H␈↓That␈α⊗is,␈α∃the␈α⊗pragmatics␈α⊗is␈α∃specified␈α⊗by␈α∃some␈α⊗canonical␈α⊗compiler␈α∃producing␈α⊗code␈α⊗for␈α∃some
␈↓ ↓H␈↓well-defined␈α∀simple␈α∀machine.␈α∀ The␈α∀meaning␈α∀of␈α∀a␈α∀program␈α∀is␈α∀the␈α∀outcome␈α∀of␈α∀an␈α∀interpreter
␈↓ ↓H␈↓interpreting␈αthis␈αcode.␈α
But␈αthen,␈αto␈αunderstand␈α
the␈αmeaning␈αof␈α
a␈αparticular␈αconstruct,␈αthis␈α
proposal
␈↓ ↓H␈↓requires␈α∞that␈α∂you␈α∞understand␈α∂the␈α∞description␈α∂of␈α∞a␈α∂compiler␈α∞and␈α∂understand␈α∞the␈α∂simple␈α∞machine.
␈↓ ↓H␈↓Two␈α∞problems␈α∞arise␈α∞immediately.␈α∞Compilers␈α∞are␈α∞not␈α∞particularly␈α∞transparent␈α∞programs.␈α∞Second,␈α
a
␈↓ ↓H␈↓very␈αsimple␈αmachine␈αmay␈αnot␈αadequately␈αreflect␈αthe␈αactual␈αmechanisms␈αused␈αin␈αan␈αimplementation.
␈↓ ↓H␈↓This aspect is important if the description is to be meaningful to an implementor.
␈↓ ↓H␈↓A␈αmore␈αfundamental␈αdifficulty␈αis␈αapparent␈αwhen␈αwe␈αconsider␈αthe␈αpractical␈αaspects␈αof␈αthis␈αproposal.
␈↓ ↓H␈↓When␈α∩asked␈α∩to␈α∩understand␈α⊃a␈α∩program␈α∩written␈α∩in␈α∩a␈α⊃high-level␈α∩language␈α∩you␈α∩think␈α∩about␈α⊃the
␈↓ ↓H␈↓␈↓↓behavior␈↓␈α
of␈α
that␈α
program␈αin␈α
a␈α
very␈α
direct␈αway.␈α
The␈α
pragmatics␈α
is␈αclose␈α
to␈α
the␈α
semantics.␈α You␈α
think
␈↓ ↓H␈↓about␈α∩the␈α∩computational␈α∩behavior␈α∪as␈α∩it␈α∩executes;␈α∩you␈α∩do␈α∪not␈α∩think␈α∩about␈α∩the␈α∩code␈α∪that␈α∩gets
␈↓ ↓H␈↓generated and then think about the execution of that code.
␈↓ ↓H␈↓A␈αmore␈αnatural␈αpragmatics␈αfor␈αthe␈αconstructs␈αis␈αgiven␈αin␈αterms␈αof␈αthe␈αexecution␈αof␈αthese␈αconstructs;
␈↓ ↓H␈↓thus␈α␈↓αeval␈↓␈αis␈αthe␈αpragmatic␈αdescription␈αof␈αLISP.␈αThe␈α␈↓αeval␈↓␈αfunction␈αdescribes␈αthe␈αexecution␈αsequence
␈↓ ↓H␈↓of␈α∞a␈α∞representation␈α∞of␈α
an␈α∞arbitrary␈α∞LISP␈α∞expression.␈α∞That␈α
description␈α∞has␈α∞a␈α∞flavor␈α∞of␈α
circularity
␈↓ ↓H␈↓which␈αsome␈αfind␈α
displeasing.␈αHowever␈αsome␈α
circularity␈αin␈αdescription␈α
is␈αinevitable;␈αwe␈αmust␈α
assume
␈↓ ↓H␈↓that␈αsomething␈αis␈αknown␈α
and␈αdoes␈αnot␈αrequire␈αfurther␈α
explication.␈α If␈αlanguage␈αL␈↓β1␈↓␈αis␈α
described␈αin
␈↓ ↓H␈↓terms of a simpler language L␈↓β2␈↓ then either L␈↓β2␈↓ is "self evident" or a description L␈↓β2␈↓ must be given.
␈↓ ↓H␈↓So,␈α∞realistically,␈α∞the␈α∞choice␈α∞is␈α∞where␈α∞to␈α∞stop,␈α∞not␈α∞whether␈α∞to␈α∞stop.␈α∞ The␈α∞LISP␈α∞position␈α∞is␈α∂that␈α∞the
␈↓ ↓H␈↓language␈α∞and␈α∞data␈α
structures␈α∞are␈α∞sufficiently␈α∞simple␈α
that␈α∞self-description␈α∞is␈α∞satisfactory.␈α
Attempts
␈↓ ↓H␈↓have␈α
been␈α
made␈αto␈α
give␈α
non-circular␈α
interpreter-based␈αdescriptions␈α
of␈α
semantics␈α
for␈αlanguages␈α
other
␈↓ ↓H␈↓than␈α∪LISP.␈α∪ There␈α∪is␈α∪a␈α∪Vienna␈α∩Definition␈α∪Language␈α∪([Weg 72])␈α∪description␈α∪of␈α∪PL/1,␈α∪and␈α∩a
␈↓ ↓H␈↓description␈α⊃of␈α⊂ALGOL␈α⊃68␈α⊃([Alg 75])␈α⊂by␈α⊃a␈α⊃Markov␈α⊂algorithm.␈α⊃Both␈α⊃these␈α⊂attempts␈α⊃result␈α⊃in␈α⊂a
␈↓ ↓H␈↓description which is long and unmanageable for all but the most persistent reader.
␈↓ ↓H␈↓There␈α
are␈α
some␈α
compelling␈α
reasons␈α
for␈α
deciding␈α
on␈α
direct␈α
circularity.␈α
First,␈α
you␈α
need␈α
only␈αlearn␈α
one
␈↓ ↓H␈↓language.␈α∩ If␈α⊃the␈α∩specification␈α∩is␈α⊃given␈α∩the␈α⊃source␈α∩language,␈α∩then␈α⊃you␈α∩learn␈α∩the␈α⊃programming
␈↓ ↓H␈↓language␈αand␈αthe␈αspecification␈αlanguage␈αat␈αthe␈αsame␈αtime.␈α Second,␈αsince␈αthe␈αevaluator␈αis␈αwritten␈α
in
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓operational,␈αand␈α
denotational.␈αWe␈α
won't␈αgo␈α
into␈αdetails␈α
here,␈αbut␈α
see␈α[Men 64]␈α
for␈αthe␈α
mathematical
␈↓ ↓H␈↓logic␈α⊃and␈α⊃[Dav 76]␈α⊃for␈α⊃a␈α⊃study␈α⊃of␈α⊃the␈α⊃interrelationships;␈α⊃see␈α⊃[Hoa 69]␈α⊃for␈α⊃a␈α⊃discussion␈α∩of␈α⊃the
␈↓ ↓H␈↓axiomatic school; we will say more about the operational and denotational schools in this section.
␈↓ ↓H␈↓␈↓π 102␈↓ But see [Pra 73] for a contrary position.
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 149␈↓
␈↓ ↓H␈↓the␈α∪language,␈α∪we␈α∪can␈α∪understand␈α∪the␈α∩language␈α∪by␈α∪understanding␈α∪the␈α∪workings␈α∪of␈α∪the␈α∩single
␈↓ ↓H␈↓program,␈α∂␈↓αeval␈↓;␈α∂and␈α∂if␈α∞we␈α∂wish␈α∂to␈α∂modify␈α∞the␈α∂pragmatics,␈α∂we␈α∂need␈α∞change␈α∂only␈α∂one␈α∂collection␈α∞of
␈↓ ↓H␈↓high-level␈α
programs.␈α
If␈α
we␈α
wished␈αto␈α
add␈α
new␈α
language␈α
constructs␈αto␈α
LISP␈α
we␈α
need␈α
only␈αmodify
␈↓ ↓H␈↓␈↓αeval␈↓␈α
so␈α
that␈α
it␈α
recognizes␈αan␈α
occurrence␈α
of␈α
that␈α
new␈α
construct,␈αand␈α
add␈α
a␈α
function␈α
to␈α
describe␈αthe
␈↓ ↓H␈↓interpretation␈α∞of␈α
the␈α∞construct.␈α
That␈α∞modification␈α
might␈α∞be␈α
extensive,␈α∞but␈α
it␈α∞will␈α
be␈α∞a␈α
controlled
␈↓ ↓H␈↓revision rather than a complete reprogramming effort.
␈↓ ↓H␈↓There␈αis␈αanother␈αcommon␈α
method␈αfor␈αspecifying␈αthe␈α
pragmatics␈αof␈αa␈αprogramming␈α
language.␈αThe
␈↓ ↓H␈↓Algol␈α∞report␈α∞([Alg 63])␈α∞introduced␈α∞a␈α∞standard␈α
for␈α∞syntax␈α∞specification:␈α∞the␈α∞BNF␈α∞equation.␈α∞It␈α
also
␈↓ ↓H␈↓gave␈α∞a␈α∞reasonably␈α∞precise␈α∞description␈α∞of␈α∂the␈α∞pragmatics␈α∞of␈α∞Algol␈α∞statements␈α∞in␈α∂natural␈α∞language.
␈↓ ↓H␈↓The␈α∩style␈α∩of␈α∩presentation␈α∪was␈α∩concise␈α∩and␈α∩clear,␈α∩but␈α∪suffers␈α∩from␈α∩the␈α∩imprecision␈α∪of␈α∩natural
␈↓ ↓H␈↓language.␈α∩ Regardless,␈α∩this␈α∩style␈α∩of␈α∩description␈α∩is␈α∩quite␈α∩common␈α∩and␈α∩is␈α∩very␈α∩useful.␈α∪A␈α∩recent
␈↓ ↓H␈↓report ([Moor 75a])␈α
on␈α
the␈αpragmatics␈α
of␈α
InterLISP␈αused␈α
this␈α
descriptive␈αstyle.␈α
If␈α
the␈α
language␈αis
␈↓ ↓H␈↓quite␈α∞complex,␈α∞then␈α∞a␈α∞formal␈α∞description␈α∞can␈α∞be␈α∞equally␈α∞complex.␈α∞In␈α∞Section 4.8␈α∞we␈α∞will␈α∞see␈α
that
␈↓ ↓H␈↓our interpreter definition will extend nicely to richer subsets of LISP.
␈↓ ↓H␈↓Regardless␈α∞of␈α∞the␈α∞descriptive␈α∞method␈α∞used,␈α
a␈α∞language␈α∞description␈α∞should␈α∞not␈α∞attempt␈α∞to␈α
explain
␈↓ ↓H␈↓everything␈αabout␈αa␈αlanguage.␈α It␈αneed␈αonly␈αexplain␈αwhat␈αneeds␈αexplaining.␈α You␈αmust␈αassume␈αthat
␈↓ ↓H␈↓your␈α≥reader␈α≤understands␈α≥something␈α≤...␈α≥.␈α≤McCarthy:␈α≥␈↓↓`Nothing␈α≤can␈α≥be␈α≤explained␈α≥to␈α≤a
␈↓ ↓H␈↓↓stone'␈↓ [McC 66].␈α⊂ A␈α⊂description␈α⊂of␈α⊂a␈α⊂language␈α∂must␈α⊂be␈α⊂natural␈α⊂and␈α⊂must␈α⊂match␈α⊂the␈α∂expressive
␈↓ ↓H␈↓power␈α
of␈α
the␈α
language.␈α
That␈αis,␈α
it␈α
should␈α
model␈α
how␈α
the␈αconstructs␈α
are␈α
to␈α
be␈α
implemented.␈α What␈α
is
␈↓ ↓H␈↓needed␈α∃is␈α∃a␈α∃description␈α∃which␈α∃exploits,␈α∃rather␈α∃than␈α∃ignores,␈α∃the␈α∃structure␈α∃of␈α∃the␈α∀language.
␈↓ ↓H␈↓Mathematical␈α∂notation␈α∂is␈α∞no␈α∂substitute␈α∂for␈α∞clear␈α∂thought,␈α∂but␈α∞we␈α∂believe␈α∂careful␈α∂formulations␈α∞of
␈↓ ↓H␈↓semantics␈α⊂will␈α⊂lead␈α⊂to␈α⊂additional␈α⊂insights␈α⊃in␈α⊂the␈α⊂pragmatics␈α⊂of␈α⊂language␈α⊂design␈α⊂␈↓π 103␈↓.␈α⊃ The␈α⊂task
␈↓ ↓H␈↓requires␈α
new␈α
mathematical␈α
tools␈α
to␈α
model␈α
the␈α
language␈α
constructs,␈α
and␈α
requires␈α
increased␈α
care␈α
on
␈↓ ↓H␈↓the part of the language designer.
␈↓ ↓H␈↓Let's␈αlook␈αat␈αthe␈α
issue␈αof␈αsyntax␈αfor␈α
a␈αmoment.␈α A␈αsatisfactory␈α
description␈αof␈αmuch␈αof␈α
programming
␈↓ ↓H␈↓language␈α⊃syntax␈α⊃is␈α⊃standard␈α⊂BNF.␈α⊃ The␈α⊃BNF␈α⊃is␈α⊃a␈α⊂generative,␈α⊃or␈α⊃synthetic␈α⊃grammar␈α⊃since␈α⊂the
␈↓ ↓H␈↓rewriting␈α⊂rules␈α∂specify␈α⊂how␈α⊂to␈α∂␈↓↓generate␈↓␈α⊂well␈α⊂formed␈α∂strings.␈α⊂ An␈α⊂evaluator,␈α∂on␈α⊂the␈α⊂other␈α∂hand,
␈↓ ↓H␈↓executes␈α∂the␈α∂already␈α∂existing␈α∂program.␈α∂ This␈α∂implies␈α∂that␈α∂our␈α∂evaluator␈α∂is␈α∂␈↓↓analytic␈↓␈α⊂rather␈α∂than
␈↓ ↓H␈↓synthetic; it must have some way of analyzing the structure of the given program.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 103␈↓ R. D. Tennent has invoked this approach in the design of ␈↓αQUEST␈↓ ([Ten 76]).
␈↓ ↓H␈↓␈↓↓150 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓In␈α∩[McC 62],␈α⊃John␈α∩McCarthy␈α⊃introduced␈α∩the␈α⊃concept␈α∩of␈α⊃abstract␈α∩analytic␈α⊃syntax.␈α∩The␈α∩idea␈α⊃is
␈↓ ↓H␈↓directly␈α
derivable␈α
from␈α
the␈α∞LISP␈α
experience.␈α
The␈α
syntax␈α
is␈α∞analytic,␈α
rather␈α
than␈α
synthetic,␈α∞in␈α
the
␈↓ ↓H␈↓sense␈αthat␈α
it␈αtells␈α
how␈αto␈α
take␈αprograms␈α
apart -- how␈αto␈α
recognize␈αand␈α
select␈αsubparts␈α
of␈αprograms
␈↓ ↓H␈↓using␈αpredicates␈αand␈αselector␈αfunctions␈↓π 104␈↓.␈α It␈αis␈αabstract␈αin␈αthe␈αsense␈αthat␈αit␈αmakes␈αno␈αcommitment
␈↓ ↓H␈↓to␈α∩the␈α∩external␈α⊃representation␈α∩of␈α∩the␈α⊃constitutents␈α∩of␈α∩the␈α⊃program.␈α∩ We␈α∩need␈α⊃only␈α∩be␈α∩able␈α⊃to
␈↓ ↓H␈↓recognize the occurrence of a desired construct. For example:
␈↓ ↓H␈↓αisterm <= λ[[t] or[␈↓ β8isvar[t];
␈↓ ↓H␈↓α␈↓ β8isconst[t];
␈↓ ↓H␈↓α␈↓ β8and[issum[t];isterm[addend[t]];isterm[augend[t]]]]]
␈↓ ↓H␈↓and the BNF equation:
␈↓ ↓H␈↓␈↓ ∧-<term> ::= <var> | <const> | <term> + <term>.
␈↓ ↓H␈↓␈↓αissum,␈α∞addend,␈↓␈α∞and␈α∞␈↓αaugend␈↓,␈α∞don't␈α∞really␈α∞care␈α∞whether␈α∞the␈α∞sum␈α∞is␈α∞represented␈α∞as␈α∞x+y,␈α∞or␈α∞␈↓α+[x;y]␈↓␈α
or
␈↓ ↓H␈↓␈↓α(PLUS X Y)␈↓␈α∂or␈α∂␈↓↓xy+␈↓.␈α∂ The␈α∂different␈α∂external␈α∂representations␈α∂are␈α∂reflections␈α∂of␈α∂different␈α∞concrete
␈↓ ↓H␈↓syntaxes;␈α∂the␈α∂BNF␈α∞equation␈α∂above␈α∂gives␈α∂one.␈α∞ Parsing␈α∂links␈α∂a␈α∞concrete␈α∂syntax␈α∂with␈α∂the␈α∞abstract
␈↓ ↓H␈↓syntax.
␈↓ ↓H␈↓Since␈α∀the␈α∪evaluator␈α∀must␈α∪operate␈α∀on␈α∪␈↓↓some␈↓␈α∀internal␈α∪representation␈α∀of␈α∪the␈α∀source␈α∀program,␈α∪a
␈↓ ↓H␈↓representation␈αreflecting␈α
the␈αstructure␈α
of␈αthe␈α
program␈αis␈α
most␈αnatural.␈α
This␈αrepresentation␈α
is␈αmore
␈↓ ↓H␈↓commonly␈α⊂known␈α∂as␈α⊂a␈α∂parse␈α⊂tree.␈α⊂We␈α∂can␈α⊂describe␈α∂the␈α⊂evaluation␈α⊂of␈α∂a␈α⊂program␈α∂in␈α⊂terms␈α⊂of␈α∂a
␈↓ ↓H␈↓function␈α
which␈α∞operates␈α
on␈α
a␈α∞parse␈α
tree␈α
using␈α∞the␈α
predicates␈α
and␈α∞selectors␈α
of␈α
the␈α∞analytic␈α
syntax.
␈↓ ↓H␈↓Abstract␈αsyntax␈αconcerns␈αitself␈αonly␈αwith␈αthose␈αproperties␈αof␈αa␈αprogram␈αwhich␈αare␈αof␈αinterest␈αto␈αan
␈↓ ↓H␈↓evaluator.
␈↓ ↓H␈↓The␈α
Meta␈α
expression␈α
LISP␈α
constitutes␈α
a␈α
concrete␈α
syntax.␈α
The␈α
M-to-S-expression␈α
translator␈α
is␈αthe
␈↓ ↓H␈↓parser␈α
which␈α
maps␈α
the␈α
external␈α
representation␈α
onto␈α
a␈α
parse␈α
(or␈α
computational)␈α
tree.␈α
The␈αselectors
␈↓ ↓H␈↓and predicates of the analytic syntax are straightforward. Recall the BNF for LISP:
␈↓ ↓H␈↓<form>␈↓ αh::= <constant>
␈↓ ↓H␈↓␈↓ αh::= <variable>
␈↓ ↓H␈↓␈↓ αh::=<function>[<arg>; ... ;<arg>]
␈↓ ↓H␈↓␈↓ αh::= [<form> → <form>; ... ;<form> → <form>]
␈↓ ↓H␈↓␈↓ αh ....
␈↓ ↓H␈↓We␈αneed␈αto␈αwrite␈αa␈αparser␈αwhich␈αtakes␈αinstances␈αof␈αthese␈αequations␈αonto␈αan␈αinternal␈α
representation.
␈↓ ↓H␈↓Much␈α∪is␈α∪known␈α∀about␈α∪parsing␈α∪techniques␈α∪([Aho 72],␈α∀also␈α∪see␈α∪Section 9.4␈α∪and␈α∀Section 9.3)␈α∪so
␈↓ ↓H␈↓we will concentrate on the post-parse processing.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 104␈↓ We will deal with abstract ␈↓↓synthetic␈↓ syntax when we discuss compilers.
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 151␈↓
␈↓ ↓H␈↓Our␈αevaluator␈αwill␈αoperate␈αof␈αthe␈αparse␈αtree␈αand␈αwill␈αtherefore␈αneed␈αto␈αrecognize␈αrepresentations␈αof
␈↓ ↓H␈↓constants,␈α
variables,␈α
conditional␈αexpressions,␈α
and␈α
applications.␈α We␈α
need␈α
to␈αwrite␈α
a␈α
function␈αin␈α
some
␈↓ ↓H␈↓language␈α
expressing␈α
the␈α
values␈α
of␈α
these␈α
constructs.␈α
Since␈α
the␈α
proposed␈α
evaluator␈α
is␈α∞to␈α
manipulate
␈↓ ↓H␈↓parse␈αtrees,␈α
and␈αsince␈α
the␈αdomain␈αof␈α
LISP␈αfunctions␈α
␈↓↓is␈↓␈αbinary␈αtrees,␈α
it␈αshould␈α
seem␈αnatural␈α
to␈αuse
␈↓ ↓H␈↓LISP␈α⊃itself.␈α⊂ If␈α⊃this␈α⊂is␈α⊃the␈α⊂case,␈α⊃then␈α⊃we␈α⊂must␈α⊃represent␈α⊂the␈α⊃parse␈α⊂tree␈α⊃as␈α⊂a␈α⊃LISP␈α⊃S-expr␈α⊂and
␈↓ ↓H␈↓represent the selectors and recognizers as LISP functions and predicates.
␈↓ ↓H␈↓α␈↓Perhaps:␈↓α
␈↓ ↓H␈↓αisconst <= λ[[x] or[␈↓ β8numberp[x];
␈↓ ↓H␈↓α␈↓ β8eq[x;NIL];
␈↓ ↓H␈↓α␈↓ β8eq[x;T];
␈↓ ↓H␈↓α␈↓ β8and[not[atom[x]];eq[first[x];QUOTE]
␈↓ ↓H␈↓αisvar <= λ[[x] and[atom[x]; not[isconst[x]]]]
␈↓ ↓H␈↓αiscond <= λ[[x] eq[first[x];COND]]
␈↓ ↓H␈↓There␈α⊂are␈α⊂really␈α⊂two␈α⊂issues␈α⊂here:␈α⊂a␈α⊂representation␈α⊂of␈α⊂the␈α⊂analytic␈α⊂syntax␈α⊂of␈α⊂a␈α⊂language,␈α⊃and␈α⊂a
␈↓ ↓H␈↓representation␈αin␈αterms␈αof␈α
the␈αlanguage␈α␈↓↓itself␈↓.␈α In␈αconjunction,␈α
these␈αtwo␈αideas␈αgive␈αa␈α
natural␈αand
␈↓ ↓H␈↓very␈α
powerful␈α
means␈α
of␈α
specifying␈α
languages.␈α
If␈αthis␈α
style␈α
of␈α
specification␈α
is␈α
really␈α
effective,␈αthen
␈↓ ↓H␈↓we␈αshould␈α
be␈αable␈α
to␈αspecify␈α
other␈αlanguages␈α
in␈αa␈α
similar␈αfashion.␈α
One␈αof␈α
the␈αweak␈α
points␈αof␈α
LISP
␈↓ ↓H␈↓as␈α⊂a␈α⊂programming␈α⊂language␈α⊂is␈α⊂the␈α⊂insistence␈α⊂on␈α⊂binary␈α⊂tree␈α⊂representations␈α⊂of␈α⊂data␈↓π 105␈↓.␈α⊂ Many
␈↓ ↓H␈↓applications␈αcould␈αprofit␈αfrom␈αother␈αdata␈αrepresentations.␈α What␈αwe␈αwould␈αthen␈αlike␈αis␈αa␈αlanguage
␈↓ ↓H␈↓which␈α∂has␈α∂richer␈α∞data␈α∂structures␈α∂than␈α∂LISP␈α∞but␈α∂which␈α∂is␈α∞designed␈α∂to␈α∂allow␈α∂LISP-style␈α∞semantic
␈↓ ↓H␈↓specification.␈α⊂ We␈α⊃would␈α⊂be␈α⊃able␈α⊂to␈α⊃write␈α⊂an␈α⊃evaluator,␈α⊂albeit␈α⊃more␈α⊂complex␈α⊃than␈α⊂␈↓αeval␈↓,␈α⊃in␈α⊂the
␈↓ ↓H␈↓language␈α∩itself.␈α∩ The␈α∩evaluator␈α∪would␈α∩operate␈α∩on␈α∩a␈α∩representation␈α∪of␈α∩the␈α∩program␈α∩as␈α∪a␈α∩data
␈↓ ↓H␈↓structure␈α
of␈α
the␈α
language,␈α
just␈α
as␈α
␈↓αeval␈↓␈α
operates␈α
on␈α
the␈α
S-expr␈α
translation␈α
of␈α
the␈α
LISP␈α
program.␈α
The
␈↓ ↓H␈↓concrete␈α⊂syntax␈α⊂would␈α⊂be␈α⊂specified␈α∂as␈α⊂a␈α⊂set␈α⊂of␈α⊂BNF␈α∂equations,␈α⊂and␈α⊂our␈α⊂parser␈α⊂would␈α∂translate
␈↓ ↓H␈↓strings into parse trees.
␈↓ ↓H␈↓In outline, to specify a construct we must have at least the following:
␈↓ ↓H␈↓␈↓ ¬_␈↓↓1.␈↓ A concrete production.
␈↓ ↓H␈↓␈↓ ¬_␈↓↓2.␈↓ An abstract data type.
␈↓ ↓H␈↓␈↓ ¬_␈↓↓3␈↓. A mapping from ␈↓↓1␈↓ to ␈↓↓2␈↓.
␈↓ ↓H␈↓␈↓ ¬_␈↓↓4.␈↓ An evaluator for the abstract type.
␈↓ ↓H␈↓In␈α_Chapter 8␈α_we␈α_will␈α_sketch␈α_a␈α_recent␈α_LISP-like␈α_language,␈α_EL1,␈α_which␈α_␈↓↓does␈↓␈α→apply␈α_these
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 105␈↓␈α
Many␈α
`production'␈α
versions␈α
of␈α
LISP␈α
have␈α
array,␈α
string,␈α
and␈α
even␈α
record␈α
structures␈α
available␈α
for
␈↓ ↓H␈↓use.␈α
However␈αthe␈α
programmer␈αmust␈α
explicitly␈α
request␈αand␈α
manipulate␈αsuch␈α
storage␈α
structures.␈αWe
␈↓ ↓H␈↓would␈αrather␈αdevelop␈αtechniques␈αin␈αwhich␈αthe␈αstorage␈αstructures␈αare␈α␈↓↓implied␈↓␈αeither␈αby␈αthe␈αtypes␈αof
␈↓ ↓H␈↓operations␈α
desired,␈α
or␈α
by␈α
the␈α
specification␈α
of␈α
the␈α
abstract␈α
data␈α
struture,␈α
or␈α
by␈α
interaction␈α
between
␈↓ ↓H␈↓the programming system and the user.
␈↓ ↓H␈↓␈↓↓152 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓principles␈↓π 106␈↓.
␈↓ ↓H␈↓From␈αa␈αdiscussion␈αof␈αsyntax␈αwe␈αhave␈αgravitated␈αback␈αto␈αevaluation.␈α After␈αwe␈αreduce␈αthe␈αquestions
␈↓ ↓H␈↓of␈αsyntax␈αof␈αprogramming␈αlanguages␈αto␈αquestions␈αof␈αabstract␈αsyntax␈αand␈αstripped␈αway␈αthe␈αsyntactic
␈↓ ↓H␈↓differences, how many ␈↓↓real␈↓ differences between languages are there? Semantics addresses this issue.
␈↓ ↓H␈↓Many␈α
of␈α∞the␈α
semantic␈α
ideas␈α∞in␈α
applicative␈α∞programming␈α
languages␈α
can␈α∞be␈α
captured␈α∞in␈α
␈↓λλ␈↓-calculus
␈↓ ↓H␈↓([Chu 41]).␈α⊃The␈α⊃␈↓λλ␈↓-calculus␈α⊃was␈α⊃developed␈α⊃to␈α⊃supply␈α⊃a␈α⊃formalism␈α⊃for␈α⊃discussing␈α⊃the␈α⊃notions␈α⊂of
␈↓ ↓H␈↓function␈α∩and␈α∩function␈α∩application.␈α∩Rather␈α∩than␈α∩develop␈α∩the␈α∩syntax␈α∩of␈α∩␈↓λλ␈↓-calculus,␈α∩we␈α∩will␈α∩use
␈↓ ↓H␈↓LISP-like␈α∃syntax␈α∃and␈α∀show␈α∃how␈α∃we␈α∃can␈α∀abstract␈α∃from␈α∃the␈α∀procedural␈α∃LISP␈α∃function␈α∃to␈α∀a
␈↓ ↓H␈↓mathematical function.
␈↓ ↓H␈↓Most␈α∂of␈α∞the␈α∂description␈α∞of␈α∂LISP␈α∞which␈α∂we␈α∂have␈α∞given␈α∂so␈α∞far␈α∂is␈α∞classified␈α∂as␈α∂operational.␈α∞ That
␈↓ ↓H␈↓means␈α⊂our␈α⊂informal␈α⊂description␈α⊂of␈α⊂LISP␈α⊂and␈α⊂our␈α⊂later␈α⊂description␈α⊂of␈α⊂the␈α⊂LISP␈α⊃interpreter␈α⊂are
␈↓ ↓H␈↓couched␈α∂in␈α∞terms␈α∂of␈α∂"how␈α∞does␈α∂it␈α∂work␈α∞or␈α∂operate".␈α∂Indeed␈α∞the␈α∂purpose␈α∂of␈α∞␈↓αeval␈↓␈α∂was␈α∂to␈α∞describe
␈↓ ↓H␈↓explicitly␈α∩what␈α∩happens␈α∩when␈α∩a␈α∩LISP␈α⊃expression␈α∩is␈α∩evaluated.␈α∩ We␈α∩have␈α∩seen␈α∩(page 90)␈α⊃that
␈↓ ↓H␈↓discussion␈αof␈αevaluation␈αschemes␈αis␈αnon-trivial;␈αand␈αthat␈αorder␈αof␈αevaluation␈αcan␈αeffect␈αthe␈α
outcome
␈↓ ↓H␈↓(page 20).
␈↓ ↓H␈↓However,␈αmany␈αtimes␈αthe␈α
order␈αof␈αevaluation␈αis␈α
immaterial␈α␈↓π 107␈↓.␈αWe␈αsaw␈α
on␈αpage 112␈αthat␈α␈↓αeval␈↓␈α
will
␈↓ ↓H␈↓perform␈α∂without␈α∂complaint␈α∂when␈α∂given␈α∂a␈α∂form␈α∂␈↓αf[ ... ]␈↓␈α∂supplied␈α∂with␈α∂too␈α∂many␈α⊂arguments.␈α∂ How
␈↓ ↓H␈↓much␈α
of␈α
␈↓αeval␈↓␈α
is␈α
"really"␈α∞LISP␈α
and␈α
how␈α
much␈α
is␈α∞"really"␈α
implementation?␈α
On␈α
one␈α
hand␈α∞we␈α
have
␈↓ ↓H␈↓said␈α⊂that␈α⊂the␈α∂meaning␈α⊂of␈α⊂a␈α∂LISP␈α⊂expression␈α⊂is␈α∂by definition␈α⊂what␈α⊂␈↓αeval␈↓␈α∂will␈α⊂calculate␈α⊂using␈α∂the
␈↓ ↓H␈↓representation␈α→of␈α_the␈α→expression.␈α→On␈α_the␈α→other␈α→hand,␈α_we␈α→claim␈α→that␈α_␈↓αeval␈↓␈α→is␈α→simply␈α_␈↓↓an
␈↓ ↓H␈↓↓implementation␈↓.␈α There␈αare␈αcertainly␈αother␈α
implementations;␈αi.e,␈αother␈αLISP␈αfunctions␈α
␈↓αeval␈↓βi␈↓␈αwhich
␈↓ ↓H␈↓have␈α
the␈α
same␈α∞input-output␈α
behavior␈α
as␈α∞our␈α
␈↓αeval␈↓.␈α
The␈α
position␈α∞here␈α
is␈α
not␈α∞that␈α
␈↓αeval␈↓␈α
is␈α∞wrong␈α
in
␈↓ ↓H␈↓giving␈α∀values␈α∀to␈α∀things␈α∪like␈α∀␈↓αcons[A;B;C]␈↓,␈α∀but␈α∀rather␈α∪we␈α∀want␈α∀to␈α∀know␈α∪what␈α∀is␈α∀it␈α∀that␈α∪␈↓αeval␈↓
␈↓ ↓H␈↓implements.
␈↓ ↓H␈↓This␈αother␈α
way␈αof␈α
looking␈αat␈αmeaning␈α
in␈αprogramming␈α
languages␈αis␈α
exemplified␈αby␈αdenotational␈α
or
␈↓ ↓H␈↓mathematical␈α∩semantics.␈α∪ This␈α∩perspective␈α∩springs␈α∪from␈α∩the␈α∩philosophical␈α∪or␈α∩logical␈α∪device␈α∩of
␈↓ ↓H␈↓distinguishing␈α⊂between␈α∂a␈α⊂␈↓↓representation␈↓␈α∂for␈α⊂an␈α∂object,␈α⊂and␈α∂the␈α⊂object␈α∂itself.␈α⊂The␈α⊂most␈α∂familiar
␈↓ ↓H␈↓example␈α⊃is␈α⊂the␈α⊃numeral-number␈α⊂distinction.␈α⊃ Numerals␈α⊂are␈α⊃notations␈α⊂(syntax)␈α⊃for␈α⊃talking␈α⊂about
␈↓ ↓H␈↓␈↓↓numbers␈↓␈α∂(semantics).␈α⊂ thus␈α∂the␈α⊂Arabic␈α∂␈↓↓numerals␈↓␈α⊂␈↓α2,␈α∂02␈↓,␈α∂the␈α⊂Roman␈α∂numeral␈α⊂␈↓II␈↓,␈α∂and␈α⊂the␈α∂Binary
␈↓ ↓H␈↓notation␈α∪␈↓α10␈↓,␈α∪all␈α∪␈↓↓denote␈↓␈α∪or␈α∪represent␈α∪the␈α∪␈↓↓number␈↓␈α∪two.␈α∪In␈α∪LISP,␈α∪␈↓α(A B),␈α∪(A . (B)),␈α∪(A , B)␈↓␈α∪and
␈↓ ↓H␈↓␈↓α(A . (B . NIL))␈↓␈α∀all␈α∃are␈α∀notations␈α∀for␈α∃the␈α∀same␈α∀S-expr.␈α∃ We␈α∀want␈α∀to␈α∃say␈α∀that␈α∀a␈α∃LISP␈α∀form
␈↓ ↓H␈↓␈↓αcar[(A . B)]␈↓␈α␈↓↓denotes␈↓␈α␈↓αA␈↓,␈αor␈α␈↓αcar[A]␈↓␈αdenotes␈αundefined␈αjust␈αas␈αwe␈αsay␈αin␈αmathematics␈αthat␈α2+2␈αdenotes
␈↓ ↓H␈↓4 or 1/0 is undefined.
␈↓ ↓H␈↓Similarly,␈α⊃we␈α⊃will␈α⊂say␈α⊃that␈α⊃the␈α⊃denotational␈α⊂counterpart␈α⊃of␈α⊃a␈α⊂LISP␈α⊃function␈α⊃is␈α⊃a␈α⊂mathematical
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 106␈↓ Compare steps ␈↓↓1␈↓ through ␈↓↓4␈↓ with those on page 35.
␈↓ ↓H␈↓␈↓π 107␈↓␈α∂"One␈α∞difficulty␈α∂with␈α∞the␈α∂operational␈α∞approach␈α∂is␈α∞that␈α∂it␈α∞(frequently)␈α∂specifies␈α∞too␈α∂much":␈α∞C.
␈↓ ↓H␈↓Wadsworth.
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 153␈↓
␈↓ ↓H␈↓function␈α⊃defined␈α⊃over␈α⊃an␈α⊃appropriate␈α∩abstract␈α⊃domain.␈α⊃ Before␈α⊃proceeding,␈α⊃we␈α∩introduce␈α⊃some
␈↓ ↓H␈↓conventions to distinguish notation from ␈↓↓de␈↓notation.
␈↓ ↓H␈↓We will continue to use italics:
␈↓ ↓H␈↓␈↓ ¬≥␈↓αA, B, ..., x, ..., car, ..., (A . B) ␈↓
␈↓ ↓H␈↓as notation in LISP expressions. Gothic bold-face:
␈↓ ↓H␈↓␈↓ ∧}␈↓A, B, ..., x, ..., car, ..., (A . B)␈↓
␈↓ ↓H␈↓will represent denotations.
␈↓ ↓H␈↓Thus␈α
␈↓αA␈↓␈α
is␈α
notation␈α
for␈α␈↓A␈↓;␈α
␈↓αcar[cdr[(A . (B . C))]]␈↓␈α
denotes␈α
␈↓B␈↓;␈α
the␈αmapping,␈α
␈↓car␈↓␈α
is␈α
the␈α
denotation␈αof
␈↓ ↓H␈↓the LISP function ␈↓αcar␈↓.
␈↓ ↓H␈↓Several␈α∞areas␈α∞of␈α∞LISP␈α
must␈α∞be␈α∞subjected␈α∞to␈α∞an␈α
abstraction␈α∞process.␈α∞ In␈α∞particular,␈α∞the␈α
operations
␈↓ ↓H␈↓involved␈α∂in␈α∞the␈α∂evaluation␈α∂process␈α∞must␈α∂be␈α∞abstracted␈α∂away.␈α∂These␈α∞involve␈α∂an␈α∂abstraction␈α∞from
␈↓ ↓H␈↓LISP's␈α
call␈α
by␈α
value␈α
evaluation␈αand␈α
its␈α
left␈α
to␈α
right␈αorder␈α
of␈α
evaluation␈α
of␈α
arguments.␈α For␈α
example,
␈↓ ↓H␈↓the␈α∞operation␈α∞of␈α∞composition␈α∂of␈α∞LISP␈α∞functions␈α∞is␈α∂to␈α∞denote␈α∞mathematical␈α∞composition;␈α∂in␈α∞LISP,
␈↓ ↓H␈↓␈↓αcar[cdr[(A . (B . C))]]␈↓␈α
means␈α
apply␈α
the␈α
procedure␈α∞␈↓αcdr␈↓␈α
to␈α
the␈α
argument␈α
␈↓α(A . (B . C))␈↓␈α∞getting␈α
␈↓α(B . C)␈↓;
␈↓ ↓H␈↓apply␈α
the␈α
procedure␈α
␈↓αcar␈↓␈αto␈α
␈↓α(B . C)␈↓␈α
getting␈α
␈↓αB␈↓.␈α
Mathematically,␈αwe␈α
have␈α
a␈α
mapping␈α
␈↓car␈↓∞o␈↓cdr␈↓,␈αwhich␈α
is
␈↓ ↓H␈↓a␈αcomposition␈αof␈αthe␈α␈↓car␈↓␈αand␈α␈↓cdr␈↓␈αmappings;␈αthe␈αordered␈αpair␈α␈↓<(A . (B . C)) , B>␈↓␈αis␈αin␈αthe␈αgraph
␈↓ ↓H␈↓of␈αthis␈αcomposed␈αmapping.␈α At␈αthis␈αlevel␈αof␈αabstraction,␈αany␈αLISP␈αcharacterization␈αof␈αa␈αfunction␈αis
␈↓ ↓H␈↓equally␈α
good;␈αthe␈α
"efficiency"␈αquestion␈α
has␈αbeen␈α
abstracted␈αaway.␈α
Many␈αimportant␈α
properties␈αof␈α
real
␈↓ ↓H␈↓programs␈α
␈↓↓can␈↓␈αbe␈α
discussed␈α
in␈αthis␈α
mathematical␈αcontext;␈α
in␈α
particular,␈αquestions␈α
of␈αequivalence␈α
and
␈↓ ↓H␈↓correctness of programs are more approachable.
␈↓ ↓H␈↓As␈α
we␈αremove␈α
the␈αoperational␈α
aspects,␈αwe␈α
discover␈αa␈α
few␈αcritical␈α
properties␈αof␈α
functions␈αwhich␈α
must
␈↓ ↓H␈↓be␈α
reconciled␈α
with␈α
LISP's␈α
procedures.␈αWe␈α
must␈α
treat␈α
the␈α
ideas␈αof␈α
binding␈α
of␈α
variables,␈α
and␈αwe␈α
must
␈↓ ↓H␈↓handle the notion of function application.
␈↓ ↓H␈↓We␈α⊃know␈α⊃that␈α⊃there␈α⊃are␈α⊃at␈α⊃least␈α⊃two␈α⊃binding␈α⊃strategies␈α⊃available:␈α⊃static␈α⊃binding␈α⊃and␈α⊃dynamic
␈↓ ↓H␈↓binding;␈α↔we␈α↔know␈α↔that␈α_the␈α↔choice␈α↔of␈α↔strategy␈α_can␈α↔effect␈α↔the␈α↔resultant␈α_computation.␈α↔This
␈↓ ↓H␈↓computational difference must be studied. To illuminate the problem we take an example in LISP.
␈↓ ↓H␈↓Consider:
␈↓ ↓H␈↓α␈↓ αXλ[[z]
␈↓ ↓H␈↓α␈↓ αX␈↓ β_λ[[u]
␈↓ ↓H␈↓α␈↓ αX␈↓ β_␈↓ βXλ[[z] u[B]][C]]
␈↓ ↓H␈↓α␈↓ αX␈↓ β_ [λ[[x] cons[x;z]]] ]
␈↓ ↓H␈↓α␈↓ αX [A]
␈↓ ↓H␈↓The␈α∃dynamic␈α∃binding␈α∀strategy␈α∃will␈α∃bind␈α∀␈↓αz␈↓␈α∃to␈α∃␈↓αA␈↓;␈α∀then␈α∃bind␈α∃␈↓αu␈↓␈α∀to␈α∃the␈α∃functional␈α∀argument,
␈↓ ↓H␈↓␈↓↓154 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓␈↓αλ[[x] cons[x;z]]␈↓;␈α
next,␈α␈↓αz␈↓␈α
is␈αrebound␈α
to␈α␈↓αC␈↓,␈α
and␈αfinally␈α
␈↓αu[B]␈↓␈αis␈α
evaluated.␈αThat␈α
involves␈αbinding␈α
␈↓αx␈↓␈αto␈α
␈↓αB␈↓
␈↓ ↓H␈↓and␈αevaluating␈α␈↓αcons[x;z]␈↓.␈αSince␈αwe␈αare␈αusing␈αdynamic␈αbinding,␈αthe␈α␈↓↓latest␈↓␈αbindings␈αof␈αthe␈αvariables
␈↓ ↓H␈↓are␈αused.␈αThe␈αlatest␈αbindings␈αfor␈α␈↓αx␈↓␈αand␈α␈↓αz␈↓␈αare␈α␈↓αB␈↓␈αand␈α␈↓αC␈↓␈αrespectively,␈αand␈αthe␈αfinal␈αvalue␈αis␈αtherefore
␈↓ ↓H␈↓␈↓α(B . C)␈↓.
␈↓ ↓H␈↓We␈α
can␈αobtain␈α
static␈α
binding␈αby␈α
replacing␈α
␈↓αλ[[x] cons[x;z]]␈↓␈αby␈α
␈↓αfunction[λ[[x] cons[x;z]]]␈↓.␈α
This␈αhas␈α
the
␈↓ ↓H␈↓effect␈α∪of␈α∪associating␈α∀the␈α∪variable␈α∪␈↓αz␈↓␈α∀with␈α∪the␈α∪atom␈α∪␈↓αA␈↓.␈α∀ As␈α∪we␈α∪know,␈α∀the␈α∪final␈α∪result␈α∀of␈α∪the
␈↓ ↓H␈↓computation will be ␈↓α(B . A)␈↓.
␈↓ ↓H␈↓Before␈α∂discussing␈α∞binding␈α∂strategies␈α∞further,␈α∂we␈α∂must␈α∞strengthen␈α∂our␈α∞understanding␈α∂of␈α∂the␈α∞ideas
␈↓ ↓H␈↓underlying␈α
function␈α
application.␈α
It␈α
is␈α
this␈α
notion␈α
which␈α
a␈α
binding␈α
strategy␈α
is␈α
implementing.␈α This
␈↓ ↓H␈↓involves␈αa␈αmore␈αcareful␈αstudy␈αof␈αthe␈αnotion␈αof␈αλ-notation␈αas␈αthe␈αrepresentation␈αof␈αa␈α
function.␈α We
␈↓ ↓H␈↓shall␈α
restrict␈α
out␈α
discussion␈α
to␈α
unary␈α
λ-expressions,␈α
since␈α
n-ary␈α
functions␈α
can␈α
be␈α
represented␈α
in␈α
terms
␈↓ ↓H␈↓of unary functions:
␈↓ ↓H␈↓␈↓ ¬
␈↓λλ␈↓((x y) ␈↓λx␈↓) = ␈↓λλ␈↓((x) ␈↓λλ␈↓((y) ␈↓λx␈↓))␈↓
␈↓ ↓H␈↓What␈αproperties␈αdo␈αwe␈αexpect␈αa␈αfunction,␈αdenoted␈αby␈αa␈αλ-expression,␈αto␈αpossess?␈α For␈α
example,␈αwe
␈↓ ↓H␈↓expect␈α∩that␈α⊃a␈α∩systematic␈α⊃renaming␈α∩of␈α⊃formal␈α∩parameters␈α⊃should␈α∩not␈α⊃effect␈α∩the␈α⊃definition␈α∩of␈α⊃a
␈↓ ↓H␈↓function.
␈↓ ↓H␈↓α␈↓ β←λ[[y] x]␈↓ should denote the same function as ␈↓αλ[[w] x]␈↓.
␈↓ ↓H␈↓But
␈↓ ↓H␈↓α␈↓ βZλ[[x] λ[[y] x]][w]␈↓ is not the same as ␈↓α λ[[x] λ[[w] x]][w]␈↓
␈↓ ↓H␈↓Such␈α∪anomalies␈α∪show␈α∪that␈α∪we␈α∪need␈α∪to␈α∪be␈α∪careful␈α∪in␈α∪defining␈α∪our␈α∪substitution␈α∀rules.␈α∪ Closer
␈↓ ↓H␈↓examination␈α⊂of␈α⊂the␈α⊂last␈α∂example␈α⊂shows␈α⊂that␈α⊂the␈α⊂result␈α∂␈↓αλ[[w] w]␈↓␈α⊂would␈α⊂occur␈α⊂if␈α⊂the␈α∂substitution
␈↓ ↓H␈↓changed␈α
a␈α
non-local␈α
name␈α
(␈↓αx␈↓)␈α
into␈α
a␈αlocal␈α
name␈α
(␈↓αw␈↓).␈α
The␈α
expected␈α
result␈α
would␈α
have␈αbeen␈α
obtained
␈↓ ↓H␈↓if␈α
we␈α
had␈α
recognized␈αthe␈α
clash␈α
of␈α
names␈αand␈α
replaced␈α
the␈α
formal␈α
parameter␈α␈↓αy␈↓␈α
with␈α
a␈α
new␈αname,␈α
say
␈↓ ↓H␈↓␈↓αu␈↓, and then performed the substitution, getting ␈↓αλ[[u] w]␈↓ which is the same as ␈↓αλ[[y] w]␈↓.
␈↓ ↓H␈↓Before␈αgiving␈αa␈αsubstitution␈αrule␈αwhich␈αaccounts␈αfor␈αsuch␈αchanges␈αof␈αname␈αwe␈αwill␈αintroduce␈αsome
␈↓ ↓H␈↓new terminology.
␈↓ ↓H␈↓First,␈α⊃the␈α⊃"same␈α∩as"␈α⊃relation␈α⊃will␈α∩occur␈α⊃frequently␈α⊃in␈α⊃the␈α∩discussion;␈α⊃we␈α⊃should␈α∩establish␈α⊃some
␈↓ ↓H␈↓properties of this notion. We introduce ␈↓ ≡␈↓ to denote "is the same as"; we could therefore say
␈↓ ↓H␈↓α␈↓ ¬Qλ[[y] x]␈↓ ␈↓ ≡␈↓ ␈↓αλ[[w] x]␈↓.
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 155␈↓
␈↓ ↓H␈↓We␈αexpect␈αthat␈α␈↓ ≡␈↓␈α
obey␈αthe␈αrules␈αof␈α
equality,␈αbeing␈αa␈αreflective,␈α
transitive␈αand␈αsymmetric␈αrelation.␈α
It
␈↓ ↓H␈↓should also "substitutive" in the following sense:
␈↓ ↓H␈↓␈↓ ∧Hif ␈↓f ␈↓ ≡␈↓ g ␈↓ then ␈↓f(a) ␈↓ ≡␈↓ g(a)
␈↓ ↓H␈↓(␈↓εs␈↓):␈↓ ∧Hif ␈↓f ␈↓ ≡␈↓ g ␈↓ then ␈↓λλ␈↓((x) f) ␈↓ ≡␈↓ ␈↓λλ␈↓((x) g)␈↓
␈↓ ↓H␈↓␈↓ ∧Hif ␈↓a ␈↓ ≡␈↓ b ␈↓ then ␈↓f(a) ␈↓ ≡␈↓ f(b)
␈↓ ↓H␈↓Next,␈α∂we␈α∂need␈α∂to␈α∂talk␈α∂about␈α∂the␈α∂bindings␈α∂of␈α∂variables␈α∂more␈α∂carefully.␈α∂ A␈α∂variable,␈α∂␈↓x␈↓,␈α∂is␈α∂a␈α∂␈↓↓free
␈↓ ↓H␈↓↓variable␈↓␈↓π 108␈↓ in an expression, ␈↓λx␈↓ if:
␈↓ ↓H␈↓␈↓λx␈↓ is the variable, ␈↓x␈↓.
␈↓ ↓H␈↓␈↓λx␈↓ is an application, ␈↓f(A)␈↓, and ␈↓x␈↓ is free in ␈↓f␈↓ or ␈↓x␈↓ is free in ␈↓A␈↓.
␈↓ ↓H␈↓␈↓λx␈↓ is a ␈↓λλ␈↓-expression, ␈↓λλ␈↓((y) M)␈↓, and ␈↓x␈↓ is free in ␈↓M␈↓ and ␈↓x␈↓ is distinct from ␈↓y␈↓.
␈↓ ↓H␈↓Thus ␈↓w␈↓ is free in ␈↓λλ␈↓((x) w)␈↓.
␈↓ ↓H␈↓We can define a LISP predicate to test for free-ness:
␈↓ ↓H␈↓αisfree <= λ[[x;z]␈↓ β([is_var[z] → eq[x;z];
␈↓ ↓H␈↓α␈↓ β( is_app[z] →␈↓ ∧h[isfree[x;func[z]] → ␈↓
t␈↓α;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h ␈↓
t␈↓α → isfree[x;arg␈↓β1␈↓α[arglist[z]]]];
␈↓ ↓H␈↓α␈↓ β( eq[λ_var[z];x] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → isfree[x;body[z]]]]
␈↓ ↓H␈↓A␈αvariable␈α
is␈αa␈α
␈↓↓bound␈αvariable␈↓␈α
in␈α␈↓λx␈↓␈αif␈α
it␈αoccurs␈α
in␈α␈↓λx␈↓␈α
and␈αis␈αnot␈α
free␈αin␈α
␈↓λx␈↓.␈α For␈α
example,␈α␈↓w␈↓␈αis␈α
bound
␈↓ ↓H␈↓in ␈↓λλ␈↓((w) w)␈↓.
␈↓ ↓H␈↓Using␈α∩our␈α∪new␈α∩terminology,␈α∩we␈α∪can␈α∩say␈α∩that␈α∪a␈α∩substitution␈α∩of␈α∪the␈α∩actual␈α∩parameter␈α∪for␈α∩free
␈↓ ↓H␈↓occurrences␈α∪of␈α∪the␈α∪formal␈α∀parameter␈α∪can␈α∪be␈α∪made␈α∪provided␈α∀no␈α∪free␈α∪variables␈α∪in␈α∀the␈α∪actual
␈↓ ↓H␈↓parameter will become bound variables as a result of the substitution.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 108␈↓ Compare this definition of free with that in Section 3.7.
␈↓ ↓H␈↓␈↓↓156 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓Here is an appropriate substitution rule:
␈↓ ↓H␈↓αsubst␈↓λ'␈↓α <= λ[[x;y;z]␈↓ β8[is_var[z] → [eq[y;z] → x; ␈↓
t␈↓α → z];
␈↓ ↓H␈↓α␈↓ β8 is_app[z] → mk_app[␈↓ ¬Xsubst␈↓λ'␈↓α[x;y;func[z]];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8␈↓ ¬Xsubst␈↓λ'␈↓α[x;y;arg␈↓β1␈↓α[arglist[z]]]];
␈↓ ↓H␈↓α␈↓ β8 eq[y;λ_var[z]] → z;
␈↓ ↓H␈↓α␈↓ β8 not[isfree[y;body[z]]] → z;
␈↓ ↓H␈↓α␈↓ β8 not[isfree[λ_var[z];x]] → mk_λ[␈↓ εXλ_var[z];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8␈↓ ¬X␈↓ ε_␈↓ εXsubst␈↓λ'␈↓α[␈↓ π8x;
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8␈↓ ¬X␈↓ ε_␈↓ εX␈↓ εx␈↓ π8y;
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8␈↓ ¬X␈↓ ε_␈↓ εX␈↓ εx␈↓ π8body[z]]];
␈↓ ↓H␈↓α␈↓ β8 ␈↓
t␈↓α →␈↓ ∧_λ[[u] mk_λ[␈↓ ¬8u;
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8subst␈↓λ'␈↓α[␈↓ ε_x;
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8␈↓ ¬X␈↓ ε_y;
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8␈↓ ¬X␈↓ ε_subst␈↓λ'␈↓α[␈↓ εxu;
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8␈↓ ¬X␈↓ ε_␈↓ εX␈↓ εxλ_var[z];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬8␈↓ ¬X␈↓ ε_␈↓ εX␈↓ εxbody[z]]]]]
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_ [genvar[ ]] ]]
␈↓ ↓H␈↓where ␈↓αgenvar␈↓ is to supply a new identifier for use as a variable name.
␈↓ ↓H␈↓The substitution rule, ␈↓αsubst␈↓λ'␈↓, is used to expressed the ␈↓εb␈↓-rule of the ␈↓λλ␈↓-calculus:
␈↓ ↓H␈↓(␈↓εb␈↓):␈↓ β≥ ␈↓αapp␈↓ ␈↓ ≡␈↓ ␈↓αsubst␈↓λ'␈↓α[arg␈↓β1␈↓α[arglist[app]];λ_var[func[app]];body[func[app]]]␈↓
␈↓ ↓H␈↓where ␈↓αapp␈↓ is an anonymous λ-application.
␈↓ ↓H␈↓There␈α
is␈α
another␈α
basic␈α
rule␈αof␈α
the␈α
␈↓λλ␈↓-calculus␈α
called␈α
the␈α␈↓εa␈↓-rule.␈α
The␈α
␈↓εa␈↓-rule␈α
generalizes␈α
the␈αnotion
␈↓ ↓H␈↓that␈α∞␈↓αλ[[y] x]␈↓␈α∞denotes␈α∞the␈α∞same␈α∞function␈α∞as␈α∂␈↓αλ[[w] x]␈↓;␈α∞that␈α∞is,␈α∞subject␈α∞to␈α∞certain␈α∞restrictions,␈α∂we␈α∞can
␈↓ ↓H␈↓change the formal parameter. The ␈↓εa␈↓-rule says:
␈↓ ↓H␈↓(␈↓εa␈↓):␈↓ βd␈↓αfun␈↓ ␈↓ ≡␈↓ ␈↓αλ[[u] mk_λ[u;subst␈↓λ'␈↓α[u;λ_var[fun];body[fun]]][var]
␈↓ ↓H␈↓α␈↓ ∧P␈↓provided that ␈↓αnot[isfree[var;body[fun]]]␈↓.
␈↓ ↓H␈↓To␈αsummarize␈αthen,␈α
the␈α␈↓λλ␈↓␈αcalculus␈α
is␈αa␈αformalism.␈αThe␈α
␈↓εa␈↓␈αand␈α␈↓εb␈↓␈α
rules␈αare␈αtransformation␈αrules,␈α
and
␈↓ ↓H␈↓␈↓εs␈↓␈αexpresses␈αproperties␈αof␈αthe␈αrelation␈α␈↓ ≡␈↓␈αas␈αrules␈αof␈αinference.␈α To␈αcomplete␈αthe␈αdescription,␈αaxioms
␈↓ ↓H␈↓which␈αgovern␈αthe␈αbehavior␈αof␈α␈↓ ≡␈↓␈αas␈αan␈αequivalence␈αrelation␈αmust␈αbe␈αgiven.␈α The␈α␈↓εa␈↓␈αand␈α␈↓εb␈↓-rules␈αare
␈↓ ↓H␈↓called␈α
␈↓↓conversion␈α
rules␈↓;␈αthey␈α
express␈α
the␈αessential␈α
behavior␈α
of␈αfunctions␈α
and␈α
their␈αapplications.␈α
The
␈↓ ↓H␈↓␈↓εa␈↓␈αrule␈αformalizes␈αthe␈αnotion␈αthat␈αa␈αfunction␈α
is␈αunchanged␈αif␈αwe␈αchange␈αits␈αformal␈αparameters.␈α
This
␈↓ ↓H␈↓property␈α∞is␈α∞related␈α∂to␈α∞␈↓↓referential␈α∞transparency␈↓.␈α∞ A␈α∂language␈α∞possesses␈α∞referential␈α∂transparency␈α∞if
␈↓ ↓H␈↓the␈α∂value␈α⊂of␈α∂an␈α∂expression␈α⊂which␈α∂contains␈α∂subexpressions␈α⊂depends␈α∂only␈α∂on␈α⊂the␈α∂values␈α⊂of␈α∂those
␈↓ ↓H␈↓subexpressions.␈α∂LISP␈α∂is␈α∂␈↓↓not␈↓␈α∂a␈α∂referentially␈α∂transparent␈α∂language;␈α∂the␈α∂value␈α∂of␈α∞␈↓αλ[[x] cons[x;y]][A]␈↓
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 157␈↓
␈↓ ↓H␈↓depends␈αon␈αthe␈αenvironment␈αsurrounding␈αthis␈αexpression.␈α The␈αdifficulty␈αagain␈αis␈αthe␈αtreatment␈αof
␈↓ ↓H␈↓free␈α∪variables:␈α∪dynamic␈α∪binding␈α∪violates␈α∪referential␈α∪transparency.␈α∪The␈α∪␈↓λλ␈↓-calculus␈α∀␈↓↓does␈↓␈α∪possess
␈↓ ↓H␈↓referential␈α∞transparency.␈α∞Referential␈α
transparency␈α∞is␈α∞not␈α
simply␈α∞a␈α∞worthwhile␈α∞theoretical␈α
property;
␈↓ ↓H␈↓its␈α∞corollary,␈α
static␈α∞binding,␈α
is␈α∞a␈α
very␈α∞useful␈α
practical␈α∞property.␈α
In␈α∞programming␈α∞terms,␈α
referential
␈↓ ↓H␈↓transparency␈αmeans␈αthat␈αto␈αunderstand␈αa␈αparticular␈αprogam␈αwe␈αneed␈αonly␈αunderstand␈αthe␈αeffect␈αof
␈↓ ↓H␈↓the␈α∞subprograms␈α∞rather␈α∞than␈α∞understand␈α∞the␈α∞implementation␈α∞of␈α∞those␈α∞subprograms.␈α∞This␈α∂idea␈α∞is
␈↓ ↓H␈↓closely␈α
related␈α
to␈α
the␈αnotion␈α
of␈α
modular␈α
programming.␈α
We␈αwill␈α
discuss␈α
some␈α
further␈αimplications␈α
of
␈↓ ↓H␈↓static binding in Section 5.21␈↓π 109␈↓.
␈↓ ↓H␈↓The␈α␈↓εb␈↓-rule␈αexpresses␈αthe␈α
intent␈αof␈αfunction␈αapplication.␈α
We␈αwould␈αthen␈αexpect␈α
that␈αa␈αmodel␈αof␈α
the
␈↓ ↓H␈↓␈↓λλ␈↓-calculus␈αwould␈αhave␈αa␈αdomain␈αconsisting␈αof␈αfunctions;␈αand␈αrequire␈αthat␈αthe␈α␈↓εb␈↓-rule␈αbe␈αreflected␈αin
␈↓ ↓H␈↓the␈αmodel␈α
as␈αfunction␈α
application.␈αThe␈αequality␈α
preserving␈αproperties␈α
of␈αthe␈α␈↓εa␈↓␈α
and␈α␈↓εb␈↓␈α
rules␈αwould
␈↓ ↓H␈↓require␈αthat␈αif␈α␈↓f(a) = g(a)␈↓␈αin␈αthe␈αmodel,␈α
then␈αany␈α␈↓εa␈↓␈αor␈α␈↓εb␈↓␈αmanipulations␈αof␈αthose␈α
expressions␈αwill
␈↓ ↓H␈↓not affect that equality. Note that we are modelling ␈↓ ≡␈↓ as ␈↓=␈↓.
␈↓ ↓H␈↓We␈α
are␈α
now␈α
in␈α
a␈α
position␈α
to␈α
relate␈αbinding␈α
strategies␈α
with␈α
the␈α
ideas␈α
of␈α
substitution␈α
and␈α␈↓εb␈↓␈α
reduction.
␈↓ ↓H␈↓Static␈α∞binding␈α
is␈α∞an␈α
implementation␈α∞of␈α
the␈α∞ideas␈α
expressed␈α∞in␈α
the␈α∞␈↓εb␈↓␈α
rule.␈α∞We␈α
can␈α∞implement␈α
the
␈↓ ↓H␈↓notions␈α⊂using␈α⊂␈↓αsubst␈↓λ'␈↓␈α⊂and␈α⊂do␈α⊂explicit␈α⊂substitutions,␈α∂or␈α⊂we␈α⊂can␈α⊂simulate␈α⊂the␈α⊂substitutions␈α⊂using␈α∂a
␈↓ ↓H␈↓symbol␈αtable␈αdevice␈αas␈αLISP␈αdoes.␈αNo␈αproblems␈α
should␈αarise␈αif␈αwe␈αuse␈α␈↓αsubst␈↓λ'␈↓;␈αhowever␈αthis␈α
solution
␈↓ ↓H␈↓is␈αnot␈αterribly␈αefficient.␈α Particular␈αcare␈αis␈αneeded␈αif␈α␈↓αsubst␈↓λ'␈↓␈αis␈αto␈αbe␈αsimulated.␈αThe␈αdifficulty␈αarises
␈↓ ↓H␈↓in␈α∩adequately␈α∩modelling␈α∩the␈α⊃substitution␈α∩of␈α∩values␈α∩for␈α⊃variables␈α∩which␈α∩are␈α∩free␈α∩in␈α⊃functional
␈↓ ↓H␈↓arguments␈α∩or␈α∩functional␈α∩values.␈α∩ From␈α∩LISP,␈α∩we␈α∩know␈α∩one␈α∩solution␈α∩to␈α∩this␈α∩problem:␈α∪use␈α∩the
␈↓ ↓H␈↓␈↓αfunction␈↓␈α⊃construct.␈α∩We␈α⊃could␈α⊃simulate␈α∩the␈α⊃effect␈α⊃of␈α∩␈↓αsubst␈↓λ'␈↓␈α⊃by␈α⊃using␈α∩a␈α⊃LISP␈α⊃symbol␈α∩table␈α⊃and
␈↓ ↓H␈↓requiring that every functional argument or value be ␈↓αfunarg␈↓ ed␈↓π 110␈↓.
␈↓ ↓H␈↓From␈α∩this␈α∪standpoint,␈α∩dynamic␈α∩binding␈α∪is␈α∩simply␈α∩an␈α∪incorrect␈α∩implementation␈α∪of␈α∩substitution.
␈↓ ↓H␈↓Attempts␈α
to␈α
legitimize␈α
dynamic␈α
binding␈α
by␈α
supplying␈α
formal␈α
rules␈α
lead␈α
to␈α
difficulties.␈α
The␈αsimple
␈↓ ↓H␈↓properties␈αexpressed␈αin␈α␈↓αsubst␈↓λ'␈↓␈αand␈αthe␈α␈↓εb␈↓ rule␈αdo␈αnot␈αhold␈αfor␈αdynamic␈αbinding.␈α However,␈α
dynamic
␈↓ ↓H␈↓binding␈αis␈αa␈αvery␈αuseful␈αprogramming␈αtool.␈αIts␈αability␈αto␈αpostpone␈αbindings␈αis␈αparticularly␈αuseful␈αin
␈↓ ↓H␈↓interactive␈αprogramming␈αenvironments␈αwhere␈αwe␈αare␈αcreating␈αprogram␈αmodules␈αincrementally.␈αThe
␈↓ ↓H␈↓final word on binding strategies has not been heard.
␈↓ ↓H␈↓So␈α∀far␈α∀the␈α∀discussion␈α∀has␈α∀concentrated␈α∀on␈α∪binding␈α∀strategies.␈α∀ We␈α∀now␈α∀wish␈α∀to␈α∀discuss␈α∪the
␈↓ ↓H␈↓implications␈α
of␈α
calling␈α
style.␈α
We␈α
have␈α
discussed␈α
two␈α
calling␈α
styles:␈α
call-by-value␈α
and␈α
call-by-name;
␈↓ ↓H␈↓these␈α∀computational␈α∀devices␈α∃must␈α∀have␈α∀interpretations␈α∃in␈α∀mathematics.␈α∀The␈α∃conversion␈α∀rules
␈↓ ↓H␈↓contain␈αno␈αinstructions␈αfor␈αtheir␈αorder␈αof␈αapplication.␈α If␈αthe␈αhypotheses␈αfor␈αa␈αrule␈αis␈αsatisfied,␈αthen
␈↓ ↓H␈↓it␈αmay␈α
be␈αapplied.␈α In␈α
the␈αreduction␈α
of␈αa␈α␈↓λλ␈↓-expression␈α
there␈αmay␈αbe␈α
several␈αreductions␈α
possible␈αat
␈↓ ↓H␈↓any␈α
one␈α
time.␈α
This␈α
is␈α
as␈α
it␈α
should␈α
be;␈α
we␈α
are␈α
extracting␈α
the␈α
procedural␈α
aspects,␈α
and␈αcertainly␈α
calling
␈↓ ↓H␈↓style␈αis␈α
procedural.␈αThe␈α
order␈αof␈α
application␈αof␈α
rules␈αexpresses␈α
a␈αparticular␈α
calling␈αalgorithm.␈α If␈α
we
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 109␈↓␈α∩There␈α⊃have␈α∩been␈α⊃several␈α∩recent␈α⊃investigations␈α∩([Hew 76],␈α⊃[Sus 75],␈α∩[Ste 76b],␈α∩[Ste 76c])␈α⊃of
␈↓ ↓H␈↓statically bound LISP-like languages.
␈↓ ↓H␈↓␈↓π 110␈↓ Of course, such a claim should be proved.
␈↓ ↓H␈↓␈↓↓158 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓design␈α∃a␈α∃␈↓λλ␈↓-calculus␈α∃machine,␈α∃we␈α∃might␈α∃specify␈α∃a␈α∃preferred␈α∃order,␈α∃but␈α∃the␈α∃machine␈α∃reflects
␈↓ ↓H␈↓"␈↓↓procedure␈↓"; the calculus reflects "␈↓↓function␈↓".
␈↓ ↓H␈↓An␈α
interpretation␈α
of␈α
the␈α
conversion␈α
rules␈α
as␈α
rules␈α
of␈α
computation␈α
requires␈α
the␈α
establishment␈α∞of␈α
a
␈↓ ↓H␈↓notion␈α∪of␈α∀what␈α∪is␈α∀to␈α∪be␈α∀computed.␈α∪ The␈α∀conversion␈α∪rules␈α∀simply␈α∪state␈α∀equivalences␈α∪between
␈↓ ↓H␈↓expressions;␈αhowever␈α
the␈α␈↓εb␈↓ rule␈α
can␈αbe␈α
applied␈αin␈αa␈α
manner␈αanalogous␈α
to␈αLISP's␈α
λ-binding.␈αThat
␈↓ ↓H␈↓is,␈αit␈αcan␈αbe␈αused␈αto␈αreplace␈αan␈αapplication␈αwith␈αthe␈αappropriately␈αsubstituted␈αbody.␈αIn␈αthis␈αcontext
␈↓ ↓H␈↓the␈α∂␈↓εb␈↓ rule␈α∂is␈α∂called␈α∂a␈α∂␈↓↓reduction␈α∂rule␈↓;␈α∂and␈α∂the␈α∂application␈α∂of␈α∂the␈α∂rule␈α∂is␈α∂called␈α∂a␈α∂reduction␈α∞step.
␈↓ ↓H␈↓There are two common strategies for choosing a reduction step: applicative order and normal order.
␈↓ ↓H␈↓Applicative␈α⊂order␈α⊂reduces␈α∂right␈α⊂most␈α⊂expression;␈α⊂normal␈α∂order␈α⊂reduces␈α⊂the␈α⊂left most␈α∂expression.
␈↓ ↓H␈↓We␈αwill␈αsay␈αthat␈αa␈α␈↓λλ␈↓-expression␈αis␈αin␈α␈↓↓normal␈αform␈↓␈αif␈αit␈αcontains␈αno␈αexpression␈αreducible␈αby␈αthe␈α␈↓λβ␈↓
␈↓ ↓H␈↓rule.␈α Not␈αall␈αexpressions␈αhave␈αnormal␈αforms:␈αlet␈α␈↓εD␈↓␈αname␈α␈↓λλ␈↓((x) x(x))␈↓;␈αthen␈α␈↓εD␈↓(␈↓εD␈↓)␈↓␈αdoes␈αnot␈αhave␈αa
␈↓ ↓H␈↓normal␈α
form.␈α Every␈α
␈↓εb␈↓␈α
transformation␈αof␈α
␈↓εD␈↓␈αproduces␈α
a␈α
new␈αexpression␈α
which␈αis␈α
also␈α
␈↓εb␈↓␈αreducible.
␈↓ ↓H␈↓Not␈αall␈αreduction␈αsequences␈αyield␈αa␈αnormal␈αform:␈αwhen␈α␈↓λλ␈↓((x) y)(␈↓εD␈↓)␈↓␈αis␈αreduced␈αin␈αnormal␈αorder,␈αa
␈↓ ↓H␈↓normal form results; whereas applicative order will not yield a normal form.
␈↓ ↓H␈↓The␈αapplication␈αof␈αthe␈αreduction␈αrules␈αcan␈αbe␈αconsidered␈αto␈αbe␈αa␈αcomputation␈αscheme.␈αThe␈αprocess
␈↓ ↓H␈↓of␈α⊃reducing␈α⊃an␈α⊃expression␈α⊃is␈α⊃the␈α⊂computation,␈α⊃and␈α⊃a␈α⊃computation␈α⊃terminates␈α⊃if␈α⊃that␈α⊂reduction
␈↓ ↓H␈↓produces␈α∞a␈α∞normal␈α∞form.␈α∞ With␈α∞this␈α
interpretation,␈α∞some␈α∞computations␈α∞terminate␈α∞and␈α∞some␈α
don't.
␈↓ ↓H␈↓An␈α⊂expression␈α∂has␈α⊂a␈α∂normal␈α⊂form␈α∂just␈α⊂in␈α∂the␈α⊂case␈α∂that␈α⊂some␈α∂reduction␈α⊂sequence␈α⊂terminates.␈α∂A
␈↓ ↓H␈↓␈↓λλ␈↓-calculus␈α∞machine␈α∞([Lan 64])␈α∞can␈α∞simulate␈α∞the␈α∞reduction␈α∞rules␈α∞in␈α∞several␈α∞ways␈α∞since␈α∞no␈α∞order␈α
of
␈↓ ↓H␈↓application␈α
is␈α
specified␈α
by␈α∞the␈α
rules.␈α
Also,␈α
a␈α
machine␈α∞might␈α
perform␈α
the␈α
substitutions␈α∞directly␈α
or
␈↓ ↓H␈↓might␈α⊗simulate␈α∃the␈α⊗substitutions␈α⊗in␈α∃a␈α⊗manner␈α⊗similar␈α∃to␈α⊗LISP.␈α⊗ Finally␈α∃we␈α⊗note␈α⊗the␈α∃close
␈↓ ↓H␈↓relationships␈α∀between␈α∀reduction␈α∀orders␈α∀and␈α∀calling␈α∀styles:␈α∀applicative␈α∀order␈α∀is␈α∀most␈α∪naturally
␈↓ ↓H␈↓associated with call-by-value, and call-by-name is reflected in normal order reduction.
␈↓ ↓H␈↓These␈α∀discussions␈α∀suggest␈α∀some␈α∀interesting␈α∀problems.␈α∪ First,␈α∀there␈α∀may␈α∀well␈α∀be␈α∀two␈α∀or␈α∪more
␈↓ ↓H␈↓sequences␈αof␈αreductions␈αfor␈α
a␈α␈↓λλ␈↓-expression;␈αassuming␈αthey␈αboth␈α
terminate,␈αwill␈αthey␈αyield␈α
the␈αsame
␈↓ ↓H␈↓normal␈αforms?␈α In␈α
fact,␈αif␈αboth␈αreduction␈α
sequences␈αterminate␈αthen␈αthey␈α
result␈αin␈αthe␈α
same␈αnormal
␈↓ ↓H␈↓form. This is called the Church-Rosser theorem ([Mil 73], [Wad 74a], [Leh 73]).
␈↓ ↓H␈↓Second,␈α
if␈α
we␈α
have␈α
two␈α
␈↓λλ␈↓-expressions␈α
which␈α
reduce␈α
to␈α
distinct␈α
normal␈α
forms,␈α
are␈α
they␈α"inherently
␈↓ ↓H␈↓different"␈α␈↓λλ␈↓-expressions?␈α This␈α
requires␈αsome␈αexplanation␈αof␈α
"inherently␈αdifferent".␈α We␈α
might␈αsay
␈↓ ↓H␈↓that␈αby␈αdefinition,␈αexpressions␈αwith␈αdifferent␈αnormal␈αforms␈αare␈α"inherently␈αdifferent".␈αBut␈αthinking
␈↓ ↓H␈↓of␈α⊂␈↓λλ␈↓-expressions␈α⊂as␈α⊂functions,␈α⊂to␈α⊂say␈α⊂two␈α⊂␈↓λλ␈↓-expressions␈α⊂are␈α⊂"different"␈α⊂is␈α⊂to␈α⊂say␈α⊂we␈α⊂can␈α∂exhibit
␈↓ ↓H␈↓arguments␈αsuch␈αthat␈αthe␈αvalue␈αof␈αapplication␈αof␈αone␈αfunction␈αis␈αnot␈αequal␈αto␈αthe␈αvalue␈αof␈αthe␈αother
␈↓ ↓H␈↓function␈α∞application.␈α∞ C. Boehm␈α∞has␈α∞established␈α∞this␈α∞for␈α∞␈↓λλ␈↓-expressions␈α∞which␈α∞have␈α∞normal␈α
forms
␈↓ ↓H␈↓([Wad 71]).
␈↓ ↓H␈↓The␈α
situation␈α
changes␈αwhen␈α
we␈α
examine␈α␈↓λλ␈↓-expressions␈α
which␈α
do␈αnot␈α
have␈α
normal␈αforms.␈α
Recalling
␈↓ ↓H␈↓the␈αintuitive␈αrelationship␈αbetween␈αnon-termination␈αand␈α"no␈αnormal␈αform",␈αwe␈αmight␈αexpect␈αthat␈αall
␈↓ ↓H␈↓expressions␈α∀without␈α∀normal␈α∀form␈α∀are␈α∀"equivalent".␈α∀However,␈α∀it␈α∀can␈α∀be␈α∀shown␈α∀that␈α∀such␈α∪an
␈↓ ↓H␈↓identification␈α∩would␈α∩lead␈α∩to␈α∩contradictions.␈α∩ We␈α⊃might␈α∩also␈α∩expect␈α∩that␈α∩␈↓λλ␈↓␈α∩expressions␈α⊃without
␈↓ ↓H␈↓normal␈αforms␈αare␈α"different"␈αfrom␈αexpressions␈αwhich␈αdo␈αhave␈αnormal␈αforms.␈α This␈αis␈αalso␈αnot␈αtrue;
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 159␈↓
␈↓ ↓H␈↓[Wad 71]␈αexhibits␈α
two␈αexpressions,␈α
␈↓I␈↓␈αand␈α␈↓J␈↓␈α
with␈αand␈α
without␈αnormal␈α
form,␈αrespectively.␈α These␈α
two
␈↓ ↓H␈↓expressions␈α∞are␈α∞the␈α∞"same"␈α∞in␈α∞the␈α∞sense␈α∞that␈α∞3␈α∞and␈α∞2.99999 ...␈α∞are␈α∞the␈α∞"same";␈α∞␈↓J␈↓␈α∞is␈α∞the␈α∞limit␈α∞of␈α∞a
␈↓ ↓H␈↓sequence␈αof␈αapproximations␈αto␈α␈↓I␈↓.␈α Also,␈αwe␈αcan␈αexhibit␈αtwo␈α␈↓λλ␈↓-expressions,␈α␈↓Y␈↓β1␈↓␈αand␈α␈↓Y␈↓β2␈↓,␈αboth␈αwithout
␈↓ ↓H␈↓normal␈α
form,␈α
which␈α
are␈αdistinct␈α
in␈α
that␈α
no␈αreduction␈α
sequence␈α
will␈α
reduce␈αone␈α
to␈α
the␈α
other;␈αbut␈α
they
␈↓ ↓H␈↓are␈α"the␈αsame␈αfunction"␈αin␈αthe␈αsense␈αthat,␈αfor␈αany␈αargument,␈α␈↓a␈↓␈αwe␈αsupply,␈αboth␈αreductions␈αresult␈αin
␈↓ ↓H␈↓the same expression. That is ␈↓Y␈↓β1␈↓(a) = Y␈↓β2␈↓(a)␈↓␈↓π 111␈↓.
␈↓ ↓H␈↓The␈α∞reduction␈α∞rules␈α∞of␈α∞the␈α∞␈↓λλ␈↓-calculus␈α∞cannot␈α∞help␈α∞us.␈α∞ The␈α∞resolution␈α∞of␈α∞the␈α∞idea␈α∂of␈α∞"same-ness"
␈↓ ↓H␈↓requires␈α∞stronger␈α∞analysis␈↓π 112␈↓.␈α∞ We␈α∂can␈α∞give␈α∞an␈α∞interpretation␈α∞to␈α∂the␈α∞␈↓λλ␈↓-calculus␈α∞such␈α∞that␈α∂in␈α∞that
␈↓ ↓H␈↓interpretation␈α∩the␈α∪pairs␈α∩␈↓I␈↓␈α∪and␈α∩␈↓J␈↓,␈α∩or␈α∪␈↓Y␈↓β1␈↓␈α∩and␈α∪␈↓Y␈↓β2␈↓,␈α∩have␈α∩the␈α∪same␈α∩meaning.␈α∪This␈α∩should␈α∪be␈α∩a
␈↓ ↓H␈↓convincing␈αargument␈αfor␈αmaintaining␈αthat␈αthey␈αare␈αthe␈α"same␈αfunction"␈αeven␈αthough␈αthe␈αreduction
␈↓ ↓H␈↓rules␈α∩are␈α∪␈↓↓not␈↓␈α∩sufficient␈α∪to␈α∩display␈α∩that␈α∪equivalence␈α∩␈↓π 113␈↓.␈α∪ D.␈α∩Scott␈α∩␈↓↓has␈↓␈α∪exhibited␈α∩a␈α∪model␈α∩or
␈↓ ↓H␈↓interpretation␈α
of␈α
the␈α
␈↓λλ␈↓-calculus,␈α
and␈α
D.␈α
Park␈α
has␈αshown␈α
the␈α
equivalence␈α
in␈α
this␈α
model␈α
of␈α
␈↓Y␈↓β1␈↓␈αand
␈↓ ↓H␈↓␈↓Y␈↓β2␈↓, and C. Wadsworth as shown the equivalence of ␈↓I␈↓ and ␈↓J␈↓.
␈↓ ↓H␈↓As␈α∂we␈α⊂said␈α∂at␈α∂the␈α⊂beginning␈α∂of␈α∂the␈α⊂section,␈α∂this␈α∂calculus␈α⊂was␈α∂intended␈α∂to␈α⊂explicate␈α∂the␈α⊂idea␈α∂of
␈↓ ↓H␈↓"function"␈α∞and␈α∞"function␈α
application".␈α∞ There␈α∞is␈α∞a␈α
reasonably␈α∞subtle␈α∞distinction␈α∞between␈α
Church's
␈↓ ↓H␈↓conception␈αof␈αa␈αfunction␈αas␈αa␈αrule␈αof␈αcorrespondence,␈αand␈αthe␈αusual␈αset-theoretic␈αview␈αof␈αa␈αfunction
␈↓ ↓H␈↓as␈α∂a␈α∞set␈α∂of␈α∂ordered␈α∞pairs.␈α∂ In␈α∞the␈α∂latter␈α∂setting␈α∞we␈α∂rather␈α∞naturally␈α∂think␈α∂of␈α∞the␈α∂elements␈α∂of␈α∞the
␈↓ ↓H␈↓domain and range of a function as existing ␈↓↓prior␈↓ to the specification of the function:
␈↓ ↓H␈↓␈↓ ∧5"Let ␈↓f␈↓ be the function ␈↓{<x,1>, <y,2>, ...}␈↓".
␈↓ ↓H␈↓When␈α∂we␈α∂think␈α∂of␈α∂a␈α⊂function␈α∂given␈α∂as␈α∂a␈α∂predetermined␈α∂set␈α⊂of␈α∂ordered␈α∂pairs␈α∂we␈α∂do␈α⊂not␈α∂expect
␈↓ ↓H␈↓functions␈α~which␈α~can␈α~take␈α~themselves␈α~as␈α~arguments␈α~like␈α~␈↓f(f)␈↓.␈α~Such␈α~functions␈α~are␈α~called
␈↓ ↓H␈↓␈↓↓self-applicative␈↓.␈α
Several␈α
languages,␈αincluding␈α
LISP,␈α
allow␈α
the␈αprocedural␈α
analog␈α
of␈αself␈α
applicative
␈↓ ↓H␈↓functions.␈α∃They␈α⊗are␈α∃an␈α⊗instance␈α∃of␈α∃functional␈α⊗arguments (Section 3.10).␈α∃ The␈α⊗LISP␈α∃function
␈↓ ↓H␈↓discussed␈αin␈αthe␈αproblem␈αon␈αpage 135␈αis␈αan␈αinstance␈αof␈αa␈αself-applicative␈αLISP␈αfunction.␈α Since␈αwe
␈↓ ↓H␈↓can␈αdeal␈αwith␈αself-application␈αas␈αa␈αprocedural␈αconcept␈αat␈αleast,␈αperhaps␈αsome␈αof␈αthis␈αunderstanding
␈↓ ↓H␈↓will help with the mathematical questions.
␈↓ ↓H␈↓The␈α∂calculus␈α∂is␈α∂an␈α⊂appropriate␈α∂tool␈α∂for␈α∂studying␈α⊂self-application␈α∂since␈α∂any␈α∂␈↓λλ␈↓-expression␈α⊂may␈α∂be
␈↓ ↓H␈↓applied␈α
to␈α
any␈α∞␈↓λλ␈↓-expression,␈α
including␈α
itself␈↓π 114␈↓.␈α∞ Compare␈α
this␈α
with␈α∞the␈α
condition␈α
in␈α∞LISP␈α
when
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 111␈↓ Note that ␈↓f(a)␈↓ may have a normal form even though ␈↓f␈↓ does not.
␈↓ ↓H␈↓␈↓π 112␈↓␈α∞The␈α∞interpretation␈α∞of␈α∞"same-ness"␈α∞which␈α∞we␈α
have␈α∞been␈α∞using␈α∞is␈α∞that␈α∞of␈α∞extensional␈α
equality.
␈↓ ↓H␈↓That␈α∞is,␈α∞two␈α∞functions␈α∞are␈α∞considered␈α∞the␈α∂same␈α∞function␈α∞if␈α∞no␈α∞differences␈α∞can␈α∞be␈α∂detected␈α∞under
␈↓ ↓H␈↓application of the functions to any arguments.
␈↓ ↓H␈↓␈↓π 113␈↓␈α∪This␈α∩demonstration␈α∪also␈α∩gives␈α∪credence␈α∩to␈α∪the␈α∩position␈α∪that␈α∩the␈α∪meaning␈α∪transcends␈α∩the
␈↓ ↓H␈↓reduction rules. Compare the incompleteness results of K. Godel ([Men 64]).
␈↓ ↓H␈↓␈↓π 114␈↓␈α∩There␈α⊃are␈α∩logical␈α∩difficulties,␈α⊃like␈α∩Russell's␈α⊃paradox,␈α∩which␈α∩arise␈α⊃if␈α∩we␈α∩allow␈α⊃unrestricted
␈↓ ↓H␈↓self-application.
␈↓ ↓H␈↓␈↓↓160 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓we␈α⊃think␈α∩of␈α⊃the␈α∩S-expression␈α⊃representation␈α∩of␈α⊃the␈α⊃language␈α∩as␈α⊃the␈α∩language␈α⊃itself.␈α∩Then␈α⊃the
␈↓ ↓H␈↓distinction between program and data disappears, just as it does in the ␈↓λλ␈↓-calculus.
␈↓ ↓H␈↓For example, in the programming language LISP, we can evaluate expressions like:
␈↓ ↓H␈↓␈↓ ∧S␈↓α((LAMBDA (X) ␈↓λx␈↓α) (LAMBDA (X) ␈↓λx␈↓α))␈↓.
␈↓ ↓H␈↓As␈α
we␈α
move␈αagain␈α
from␈α
procedural␈α
notions␈αto␈α
more␈α
denotational␈αconcepts␈α
we␈α
should␈α
remark␈αthat
␈↓ ↓H␈↓denotational interpretations have been introduced before. When we said (page 105) that:
␈↓ ↓H␈↓α␈↓ ¬αf[a␈↓β1␈↓α; ...; a␈↓βn␈↓α] = eval[(F A␈↓β1␈↓α ... A␈↓βn␈↓α)],
␈↓ ↓H␈↓we␈α⊂were␈α⊂relating␈α⊂a␈α⊂denotational␈α⊂notion␈α⊂with␈α⊃an␈α⊂operational␈α⊂notion.␈α⊂The␈α⊂left␈α⊂hand␈α⊂side␈α⊃of␈α⊂this
␈↓ ↓H␈↓equation␈αis␈αdenotational;␈αit␈αexpresses␈αa␈αfunctional␈αrelationship.␈αThe␈αright␈αhand␈αside␈αis␈αoperational,
␈↓ ↓H␈↓expressing␈α∩a␈α⊃procedure␈α∩call.␈α⊃ A␈α∩proper␈α⊃mathematical␈α∩theory␈α⊃should␈α∩allow␈α⊃us␈α∩to␈α⊃state␈α∩such␈α⊃an
␈↓ ↓H␈↓equation␈α
precisely␈α
and␈αshould␈α
contain␈α
methods␈αwhich␈α
allow␈α
us␈α
to␈αdemonstrate␈α
the␈α
correctness␈αof␈α
the
␈↓ ↓H␈↓assertion.␈α Recent␈αresearch␈α([Sco 70],␈α[Sco 73],␈α
[Wad 71],␈α[Gor 73],␈α[Gor 75])␈αhas␈αbegun␈α
to␈αdevelop
␈↓ ↓H␈↓such mathematical methods.
␈↓ ↓H␈↓This␈α
denotational-operational␈α
distinction␈α
is␈α
appropriate␈α∞in␈α
a␈α
more␈α
general␈α
context.␈α
When␈α∞we␈α
are
␈↓ ↓H␈↓presented␈α∪with␈α∪someone's␈α∪program␈α∪and␈α∪asked␈α∩"what␈α∪does␈α∪it␈α∪compute?"␈α∪we␈α∪usually␈α∪begin␈α∩our
␈↓ ↓H␈↓investigation␈αoperationally,␈αdiscovering␈α"what␈αdoes␈αit␈α␈↓↓do␈↓?"␈↓π 115␈↓.␈α Frequently,␈αby␈αtracing␈αits␈αexecution,
␈↓ ↓H␈↓we can discover a denotational description: E.g., "ah! it computes the square root".
␈↓ ↓H␈↓When␈α␈↓αgreat␈αmother␈↓␈αwas␈αpresented␈αit␈αwas␈αgiven␈αas␈αan␈αoperational␈αexercise,␈αwith␈αthe␈α
primary␈αintent
␈↓ ↓H␈↓of␈α⊂introducing␈α⊂the␈α∂LISP␈α⊂evaluation␈α⊂process␈α⊂without␈α∂involving␈α⊂complicated␈α⊂names␈α⊂and␈α∂concepts.
␈↓ ↓H␈↓Forms␈αinvolving␈α␈↓αgreat␈αmother␈↓␈α
were␈αevaluated␈αperhaps␈αwithout␈α
understanding␈αthe␈αdenotation,␈αbut␈α
if
␈↓ ↓H␈↓asked␈α∞"what␈α∞does␈α∞␈↓αgreat␈α∞mother␈↓␈α∞do?"␈α∞you␈α∞would␈α∞be␈α∞hard␈α∞pressed␈α∞to␈α∞give␈α∞a␈α∞comprehensible␈α
purely
␈↓ ↓H␈↓operational␈α∞definition.␈α∞However,␈α∞you␈α∞might␈α∞have␈α∞discovered␈α∞the␈α∞intended␈α∞nature␈α∞of␈α∞␈↓αgreat␈α∞mother␈↓
␈↓ ↓H␈↓yourself;␈αthen␈αit␈αwould␈αbe␈αrelatively␈αeasy␈αto␈αdescribe␈αits␈α(her)␈αbehavior.␈αIndeed,␈αonce␈αthe␈αdenotation
␈↓ ↓H␈↓of␈α(␈↓αgreat␈α(mother␈↓␈α(has␈α'been␈α(discovered␈α(questions␈α(like␈α'"What␈α(is␈α(the␈α(value␈α'of
␈↓ ↓H␈↓␈↓αtgmoaf[(CAR (QUOTE (A . B)))]␈↓?␈α"␈αare␈αusually␈αanswered␈αby␈αusing␈αthe␈αdenotation␈αof␈α␈↓αtgmoaf␈↓:␈α"what
␈↓ ↓H␈↓is the value of ␈↓αcar[(A . B)]␈↓?"
␈↓ ↓H␈↓In␈α
discussing␈αmodels␈α
for␈αLISP,␈α
we␈αwill␈α
parallel␈αour␈α
development␈αof␈α
interpreters␈αfor␈α
LISP␈αsince␈α
each
␈↓ ↓H␈↓subset,␈α␈↓αtgmoaf,␈αtgmoafr␈↓,␈αand␈α␈↓αeval␈↓,␈αwill␈αalso␈αintroduce␈αnew␈αproblems␈αfor␈αour␈αmathematical␈αsemantics.
␈↓ ↓H␈↓Our␈α
first␈α
LISP␈αsubset␈α
considers␈α
functions,␈αcomposition,␈α
and␈α
constants.␈α Constants␈α
will␈α
be␈αelements
␈↓ ↓H␈↓of␈α⊂our␈α∂domain␈α⊂of␈α⊂interpretation.␈α∂ That␈α⊂domain␈α∂will␈α⊂include␈α⊂the␈α∂S-expressions␈α⊂since␈α⊂␈↓↓most␈↓␈α∂LISP
␈↓ ↓H␈↓expressions␈αdenote␈αS-exprs;␈α
since␈αmany␈αof␈αour␈α
LISP␈αfunctions␈αare␈α
partial␈αfunctions,␈αit␈αis␈α
convenient
␈↓ ↓H␈↓to␈αtalk␈α
about␈αthe␈αundefined␈α
value,␈α␈↓λB␈↓.␈αWe␈α
wish␈αto␈αextend␈α
our␈αpartial␈αfunctions␈α
to␈αbe␈α␈↓↓total␈↓␈α
functions
␈↓ ↓H␈↓on an extended domain. As before (page 12), we shall call this extended domain ␈↓ S␈↓.
␈↓ ↓H␈↓␈↓ ¬E␈↓ S␈↓ = ␈↓<sexpr>␈↓ ∪ {␈↓λB␈↓}.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 115␈↓␈αAnother␈αcommon␈α
manifestation␈αof␈αthis␈α"denotation"␈α
phenomonon␈αis␈αthe␈α
common␈αprogrammer
␈↓ ↓H␈↓complaint: "It's easier to write your own than to understand someone else's."
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 161␈↓
␈↓ ↓H␈↓Before␈α
we␈α
can␈α
discuss␈α
the␈α
properties␈αof␈α
mathematical␈α
functions␈α
denoted␈α
by␈α
LISP␈α
functions,␈αwe␈α
must
␈↓ ↓H␈↓give␈αmore␈αcareful␈αstudy␈αto␈αthe␈αnature␈αof␈αdomains.␈α Our␈αprimitive␈αdomain␈αis␈α␈↓<atom>␈↓.␈α Its␈αintuitive
␈↓ ↓H␈↓structure␈α⊂is␈α⊂quite␈α⊂simple,␈α⊂basically␈α⊂just␈α⊂a␈α∂set␈α⊂of␈α⊂atoms␈α⊂or␈α⊂names␈α⊂with␈α⊂no␈α⊂inherent␈α∂relationships
␈↓ ↓H␈↓among␈α∀them.␈α∀ Another␈α∀primitive␈α∀domain␈α∀is␈α∪␈↓ Tr␈↓,␈α∀the␈α∀domain␈α∀of␈α∀truth␈α∀values.␈α∀ The␈α∪domain
␈↓ ↓H␈↓␈↓<sexpr>␈↓␈αis␈αmore␈αcomplex;␈αit␈αis␈αa␈αset␈αof␈αelements,␈αbut␈αmany␈αelements␈αare␈αrelated.␈αIn␈αour␈αdiscussion
␈↓ ↓H␈↓of␈α
␈↓<sexpr>␈↓␈α
on␈α
page 6␈α∞we␈α
made␈α
it␈α
clear␈α∞that␈α
there␈α
is␈α
more␈α∞than␈α
syntax␈α
involved.␈α
We␈α∞could␈α
say
␈↓ ↓H␈↓that␈α∂for␈α∂␈↓s␈↓β1␈↓␈α∂and␈α∂␈↓s␈↓β2␈↓␈α∂in␈α∂␈↓<sexpr>␈↓␈α∂the␈α∂essence␈α∂of␈α∂"dotted␈α∂pair"␈α∂is␈α∂contained␈α∂in␈α∂the␈α∂concept␈α∂of␈α∞the
␈↓ ↓H␈↓set-theoretic␈α∞ordered␈α∞pair,␈α∞<␈↓s␈↓β1␈↓,␈↓s␈↓β2␈↓>.␈α∞Thus␈α∞the␈α∞"meaning"␈α∞of␈α∞the␈α∞set␈α∞of␈α∞dotted␈α∞pairs␈α∞is␈α∂captured␈α∞by
␈↓ ↓H␈↓Cartesian product, ␈↓<sexpr> ␈↓ x␈↓ <sexpr>␈↓.
␈↓ ↓H␈↓Let's continue the analysis of:
␈↓ ↓H␈↓␈↓ ∧I<sexpr> ::= <atom> | (<sexpr> . <sexpr>).
␈↓ ↓H␈↓We␈αare␈αtrying␈αto␈αinterpret␈αthis␈αBNF␈αequation␈αas␈αa␈αdefinition␈αof␈αthe␈αdomain␈α␈↓<sexpr>␈↓.␈αReasonable
␈↓ ↓H␈↓interpretations␈α⊂of␈α⊃"::="␈α⊂and␈α⊃"|"␈α⊂appear␈α⊃to␈α⊂be␈α⊃equality␈α⊂and␈α⊃set-theoretic␈α⊂union,␈α⊃respectively.␈α⊂This
␈↓ ↓H␈↓results in the equation:
␈↓ ↓H␈↓␈↓ ∧∪<sexpr> = <atom> ␈↓ ∪␈↓ <sexpr> ␈↓ x␈↓ <sexpr> ␈↓.
␈↓ ↓H␈↓This␈α
looks␈αlike␈α
an␈αalgebraic␈α
equation,␈αand␈α
as␈α
such,␈αmay␈α
or␈αmay␈α
not␈αhave␈α
solutions.␈α This␈α
particular
␈↓ ↓H␈↓"domain␈α
equation"␈αhas␈α
a␈αsolution:␈α
the␈αS-exprs.␈α
There␈αis␈α
a␈αnatural␈α
mapping␈αof␈α
BNF␈αequations␈α
onto
␈↓ ↓H␈↓such␈α"domain␈αequations",␈αand␈αthe␈αsolutions␈αto␈αthe␈αdomain␈αequations␈αare␈αsets␈αsatisfying␈αthe␈αabstract
␈↓ ↓H␈↓essence␈α
of␈αthe␈α
BNF.␈αThe␈α
mapping␈αprocess␈α
is␈αalso␈α
applicable␈αto␈α
the␈αlanguage␈α
constructs.␈α Consider
␈↓ ↓H␈↓the BNF equations for a simple applicative subset of LISP:
␈↓ ↓H␈↓␈↓ β∃<form> ::= <variable> | ␈↓αλ␈↓[[<variable>] <form>] | <variable [<form>]
␈↓ ↓H␈↓We␈α∞would␈α∂like␈α∞to␈α∂describe␈α∞the␈α∞denotations␈α∂of␈α∞these␈α∂equations␈α∞in␈α∞a␈α∂style␈α∞similar␈α∂to␈α∞that␈α∂used␈α∞for
␈↓ ↓H␈↓<sexpr>'s.␈α
The␈αdenotations␈α
of␈α
the␈αexpressions,␈α
<form>,␈α
of␈αapplications,␈α
<variable>[form>],␈α
and␈αof
␈↓ ↓H␈↓the␈α(variables,␈α'<variables>,␈α(are␈α(just␈α'elements␈α(of␈α(␈↓ S␈↓.␈α' Expressions␈α(of␈α(the␈α'form
␈↓ ↓H␈↓"␈↓αλ␈↓[[<variable>] <form>]"␈αdenote␈αfunctions␈αfrom␈α␈↓ S␈↓␈αto␈α␈↓ S␈↓.␈αWrite␈αthat␈αset␈αas␈α␈↓ S␈↓→␈↓ S␈↓.␈αThen␈αour␈αdomain
␈↓ ↓H␈↓equation is expressed:
␈↓ ↓H␈↓␈↓ ¬↑␈↓ S␈↓ = ␈↓ S␈↓→␈↓ S ∪ S␈↓
␈↓ ↓H␈↓This␈α
equation␈αhas␈α
no␈α
␈↓↓interesting␈↓␈αsolutions.␈α
A␈α
simple␈αcounting␈α
argument␈α
will␈αestablish␈α
that␈αunless␈α
a
␈↓ ↓H␈↓domain␈α␈↓C␈↓␈αis␈αa␈αsingle␈αelement,␈αthen␈αthe␈αnumber␈αof␈αfunctions␈αin␈α␈↓C→C␈↓␈αis␈αgreater␈αthan␈αthe␈αnumber␈αof
␈↓ ↓H␈↓elements␈α
in␈α
␈↓C␈↓.␈α
This␈α
does␈α
␈↓↓not␈↓␈α
say␈α
that␈α
there␈α
are␈α
no␈α
models␈α
for␈α
this␈α
LISP␈α
subset;␈α
it␈α
says␈α
that␈α
our
␈↓ ↓H␈↓interpretation of "␈↓→␈↓" is too broad.
␈↓ ↓H␈↓What␈α⊃is␈α⊂needed␈α⊃is␈α⊃an␈α⊂interpretation␈α⊃of␈α⊂functionality␈α⊃which␈α⊃will␈α⊂allow␈α⊃a␈α⊂solution␈α⊃to␈α⊃the␈α⊂above
␈↓ ↓H␈↓domain␈αequation;␈αit␈αshould␈αallow␈αa␈αnatural␈αinterpretation␈αsuch␈αthat␈αthe␈αproperties␈αwhich␈αwe␈αexpect
␈↓ ↓H␈↓functions␈α∪to␈α∪possess␈α∪are␈α∪true␈α∪in␈α∪the␈α∪model.␈α∪ D. Scott␈α∪gave␈α∪one␈α∪interpretation␈α∪of␈α∪"␈↓→␈↓"␈α∪for␈α∪the
␈↓ ↓H␈↓␈↓λλ␈↓-calculus,␈αdefining␈αthe␈αclass␈αof␈α"continuous␈αfunctions"␈α([Sco 70],␈α[Sco 73]).␈α This␈αclass␈αof␈αfunctions
␈↓ ↓H␈↓is␈αrestricted␈αenough␈αto␈αsatisfy␈αthe␈αdomain␈αequation,␈αbut␈αbroad␈αenough␈αto␈αact␈αas␈αthe␈αdenotations␈αof
␈↓ ↓H␈↓␈↓↓162 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓procedures␈αin␈αapplicative␈αprogramming␈αlanguages.␈α We␈αwill␈αuse␈αthe␈αnotation␈α"␈↓[␈↓D␈↓β1␈↓ ␈↓→␈↓ D␈↓β2␈↓]␈↓"␈αto␈αmean
␈↓ ↓H␈↓"the␈α∞set␈α∞of␈α∞continuous␈α∂functions␈α∞from␈α∞domain␈α∞D␈↓β1␈↓␈α∞to␈α∂domain␈α∞D␈↓β2␈↓".␈α∞ It␈α∞is␈α∞the␈α∂continuous␈α∞functions
␈↓ ↓H␈↓which␈αfirst␈αsupplied␈αa␈αmodel␈αfor␈αthe␈α␈↓λλ␈↓-calculus␈αand␈αit␈αis␈αthese␈αfunctions␈αwhich␈αsupply␈αa␈αbasis␈αfor␈αa
␈↓ ↓H␈↓mathematical model of applicative LISP ([Gor 73]).
␈↓ ↓H␈↓We␈α∂can␈α∞assume␈α∂that␈α∞the␈α∂LISP␈α∞primitives␈α∂denote␈α∞specific␈α∂continuous␈α∞functions.␈α∂For␈α∂example,␈α∞the
␈↓ ↓H␈↓mathematical␈α∞counterpart␈α∞to␈α∞the␈α∞LISP␈α∞function␈α∞␈↓αcar␈↓␈α∞is␈α∞the␈α∞mapping␈α∞␈↓car␈↓␈α∞from␈α∞␈↓ S␈↓␈α∞to␈α∞␈↓ S␈↓␈α∞defined␈α∞as
␈↓ ↓H␈↓follows:
␈↓ ↓H␈↓␈↓ αX␈↓car: [␈↓ S␈↓ → ␈↓ S␈↓]␈↓
␈↓ ↓H␈↓␈↓ αX␈↓ βxis ␈↓λB␈↓ if ␈↓t␈↓ is atomic
␈↓ ↓H␈↓␈↓ αX␈↓car(t)␈↓ βx␈↓is ␈↓t␈↓β1␈↓ if ␈↓t␈↓ is ␈↓(t␈↓β1␈↓ . t␈↓β2␈↓)
␈↓ ↓H␈↓␈↓ αX␈↓ βx␈↓is ␈↓λB␈↓ if ␈↓t␈↓ is ␈↓λB␈↓.
␈↓ ↓H␈↓Similar␈αstrategy␈αsuffices␈αto␈αgive␈αdenotations␈αfor␈αthe␈αother␈αprimitive␈αLISP␈αfunctions␈αand␈αpredicates.
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓␈↓ αX␈↓atom: [␈↓ S␈↓ → ␈↓ S␈↓]␈↓
␈↓ ↓H␈↓␈↓ αX␈↓ βxis ␈↓
f␈↓ if ␈↓t␈↓ is not atomic.
␈↓ ↓H␈↓␈↓ αX␈↓atom(t)␈↓ βx␈↓is ␈↓
t␈↓ if ␈↓t␈↓ is atomic.
␈↓ ↓H␈↓␈↓ αX␈↓ βxis ␈↓λB␈↓ if ␈↓t␈↓ is ␈↓λB␈↓.
␈↓ ↓H␈↓Notice that these functions are strict: ␈↓f(␈↓λB␈↓) = ␈↓λB␈↓.
␈↓ ↓H␈↓Corresponding␈α∀to␈α∀␈↓αtgmoaf␈↓,␈α∀we␈α∀will␈α∀have␈α∀a␈α∀function,␈α∀␈↓λD␈↓βtg␈↓,␈α∀which␈α∀maps␈α∀expressions␈α∀onto␈α∀their
␈↓ ↓H␈↓denotations.␈α Since␈α␈↓λD␈↓βtg␈↓␈αis␈αanother␈αmapping␈αlike␈α␈↓λr␈↓,␈αwe␈αwill␈αuse␈αthe␈α"␈↓∞(␈↓"␈αand␈α"␈↓∞)␈↓"␈αbrackets␈αto␈αenclose
␈↓ ↓H␈↓LISP␈αconstructs.␈α We␈αneed␈αto␈α
introduce␈αsome␈αnotation␈αfor␈αelements␈α
of␈αthe␈αsets␈α<sexpr>␈αand␈α
<form>.
␈↓ ↓H␈↓Let ␈↓ s␈↓ be a meta-variable ranging over <sexpr> and ␈↓ e␈↓ range over <form>, then we can write:
␈↓ ↓H␈↓␈↓ ¬⎇␈↓λD␈↓βtg␈↓∞(␈↓ s␈↓∞)␈↓ = ␈↓s␈↓
␈↓ ↓H␈↓␈↓ ¬␈↓λD␈↓βtg␈↓∞(␈↓αcar[␈↓ e␈↓α]␈↓∞)␈↓ = ␈↓car(␈↓λD␈↓βtg␈↓∞(␈↓ e␈↓∞)␈↓)
␈↓ ↓H␈↓with␈α
similar␈α
entries␈α
for␈α
␈↓αcdr,␈αcons,␈α
eq,␈α
␈↓and␈α
␈↓αatom␈↓.␈α
The␈α
structure␈αof␈α
this␈α
definition␈α
is␈α
very␈α
similar␈αto
␈↓ ↓H␈↓that of ␈↓αtgmoaf␈↓.
␈↓ ↓H␈↓Now␈α⊂we␈α⊂continue␈α⊂to␈α⊂the␈α⊂next␈α⊂subset␈α∂of␈α⊂LISP,␈α⊂adding␈α⊂conditional␈α⊂expressions.␈α⊂As␈α⊂we␈α⊂noted␈α∂on
␈↓ ↓H␈↓page 22,␈α∞a␈α∞degree␈α
of␈α∞care␈α∞need␈α
be␈α∞taken␈α∞when␈α
we␈α∞attempt␈α∞to␈α
interpret␈α∞conditional␈α∞expressions␈α
in
␈↓ ↓H␈↓terms␈α
of␈α
mappings.␈α
We␈α
can␈α∞simplify␈α
the␈α
problem␈α
slightly:␈α
it␈α∞is␈α
easy␈α
to␈α
show␈α
that␈α∞the␈α
conditional
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 163␈↓
␈↓ ↓H␈↓expression␈α
can␈α
be␈α
formulated␈α
in␈α
terms␈α
of␈αthe␈α
simple␈α
␈↓αif␈↓-expression:␈α
␈↓αif[p␈↓β1␈↓α;e␈↓β1␈↓α;e␈↓β2␈↓α]␈↓.␈α
We␈α
will␈α
display␈αa
␈↓ ↓H␈↓denotation␈αfor␈αsuch␈α␈↓αif␈↓␈αexpressions.␈αIt␈αwill␈αbe␈αa␈αmathematical␈αfunction,␈αand␈αtherefore␈αthe␈αevaluation
␈↓ ↓H␈↓order will have been abstracted out␈↓π 116␈↓.
␈↓ ↓H␈↓Let ␈↓αif␈↓ denote ␈↓if␈↓ where:
␈↓ ↓H␈↓␈↓ αX␈↓if: [␈↓ Tr␈↓x␈↓ S␈↓x␈↓ S␈↓ → ␈↓ S␈↓]
␈↓ ↓H␈↓␈↓ αX␈↓ ∧_␈↓is␈↓ y ␈↓if␈↓ x ␈↓is␈↓ ␈↓
t␈↓
␈↓ ↓H␈↓␈↓ αXif(x,y,z)␈↓ ∧_␈↓is ␈↓z␈↓, if ␈↓x␈↓ is ␈↓
f␈↓.
␈↓ ↓H␈↓␈↓ αX␈↓ ∧_is ␈↓λB␈↓, otherwise
␈↓ ↓H␈↓This␈α⊂interpretation␈α⊃of␈α⊂conditional␈α⊃expressions␈α⊂is␈α⊃appropriate␈α⊂for␈α⊃LISP;␈α⊂other␈α⊃interpretations␈α⊂of
␈↓ ↓H␈↓conditionals are possible. For example:
␈↓ ↓H␈↓␈↓ αX␈↓if␈↓β1␈↓: [␈↓ Tr␈↓x␈↓ S␈↓x␈↓ S␈↓ → ␈↓ S␈↓]
␈↓ ↓H␈↓␈↓ αX␈↓ ∧8␈↓is␈↓ y ␈↓if␈↓ x ␈↓is␈↓ ␈↓
t␈↓
␈↓ ↓H␈↓␈↓ αXif␈↓β1␈↓(x,y,z)␈↓ ∧8␈↓is ␈↓z␈↓, if ␈↓x␈↓ is ␈↓
f␈↓.
␈↓ ↓H␈↓␈↓ αX␈↓ ∧8is ␈↓λB␈↓ if ␈↓x␈↓ is ␈↓λB␈↓ and ␈↓y ≠ z␈↓
␈↓ ↓H␈↓␈↓ αX␈↓ ∧8is ␈↓y␈↓ if ␈↓x␈↓ is ␈↓λB␈↓ and ␈↓y = z␈↓ ␈↓π 117␈↓.
␈↓ ↓H␈↓Neither ␈↓if␈↓ nor ␈↓if␈↓β1␈↓ are strict mappings.
␈↓ ↓H␈↓To add ␈↓αif␈↓ expressions to ␈↓λD␈↓βtg␈↓, yielding ␈↓λD␈↓βtgr␈↓ we include:
␈↓ ↓H␈↓␈↓ αx␈↓λD␈↓βtgr␈↓∞(␈↓αif[␈↓ e␈↓β1␈↓α; ␈↓ e␈↓β2␈↓α; ␈↓ e␈↓β3␈↓α]␈↓∞)␈↓ = ␈↓if(␈↓λD␈↓βtgr␈↓∞(␈↓ e␈↓β1␈↓∞)␈↓, ␈↓λD␈↓βtgr␈↓∞(␈↓ e␈↓β2␈↓∞)␈↓, ␈↓λD␈↓βtgr␈↓∞(␈↓ e␈↓β3␈↓∞)␈↓)␈↓
␈↓ ↓H␈↓The␈αnext␈αconsideration␈αis␈αthe␈αdenotational␈αdescription␈αof␈αLISP␈αidentifiers.␈α Identifiers␈αname␈αeither
␈↓ ↓H␈↓S-exprs␈α⊃or␈α⊃LISP␈α⊂functions.␈α⊃ Thus␈α⊃an␈α⊂identifier␈α⊃denotes␈α⊃either␈α⊂an␈α⊃object␈α⊃on␈α⊂our␈α⊃domain␈α⊃␈↓ S␈↓␈α⊂or
␈↓ ↓H␈↓denotes␈α
a␈αfunction␈α
object.␈α
Let␈α␈↓ Fn␈↓␈α
name␈α
the␈αset␈α
of␈α
continuous␈αfunctions: ␈↓λS␈↓βn=1␈↓[␈↓ S␈↓πn␈↓ → ␈↓ S␈↓]␈↓,␈α
and␈α␈↓ Id␈↓␈α
be
␈↓ ↓H␈↓␈↓<identifier>␈↓∪␈↓λB␈↓.␈α
We␈αknow␈α
that␈α
the␈αvalue␈α
of␈α
a␈αLISP␈α
<identifier>␈α
(page 17)␈αdepends␈α
on␈αthe␈α
current
␈↓ ↓H␈↓environment. Then we might characterize the set of environments, ␈↓env␈↓, as:
␈↓ ↓H␈↓␈↓ ¬b␈↓[␈↓ Id␈↓ → ␈↓ S␈↓∪␈↓ Fn␈↓␈↓]␈↓.
␈↓ ↓H␈↓That␈αis,␈αan␈αelement␈αof␈α␈↓env␈↓␈αis␈αa␈αcontinuous␈αfunction␈αwhich␈αmaps␈αan␈αidentifier␈αeither␈αonto␈αa␈αS-expr
␈↓ ↓H␈↓or␈α∞onto␈α
an␈α∞n-ary␈α
function␈α∞from␈α
S-exprs␈α∞to␈α
S-exprs.␈α∞ This␈α
is␈α∞the␈α
essence␈α∞of␈α
the␈α∞argument␈α∞used␈α
in
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 116␈↓␈αRecall␈α
the␈αcomment␈α
of␈αWadsworth␈α
(page 152).␈αIndeed,␈α
the␈αuse␈α
of␈αconditional␈α
expressions␈αin␈α
the
␈↓ ↓H␈↓more␈αabstract␈α
representations␈αof␈αLISP␈α
functions␈αfrequently␈α
is␈αsuch␈αthat␈α
exactly␈αone␈αof␈α
the␈αp␈↓βi␈↓'s␈α
is␈α␈↓
t␈↓
␈↓ ↓H␈↓and␈αall␈αthe␈αothers␈αare␈α␈↓
f␈↓.␈αThus␈αin␈αthis␈αsetting,␈αthe␈αorder␈αof␈αevaluation␈αof␈αthe␈αpredicates␈αis␈αuseful␈αfor
␈↓ ↓H␈↓"efficiency" but not necessary to maintain the sense of the definition. See page 61.
␈↓ ↓H␈↓␈↓π 117␈↓ Basing conditional expressions on ␈↓if␈↓β1␈↓ would give ␈↓α[car[A] → 1; ␈↓
t␈↓α → 1]␈↓ value ␈↓α1␈↓.
␈↓ ↓H␈↓␈↓↓164 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓introducing␈α!␈↓αassoc␈↓␈α!(Section 3.3).␈α" Note␈α!that␈α!␈↓αassoc[x;l] = ␈↓l(x)␈↓␈α"is␈α!another␈α!instance␈α"of␈α!a
␈↓ ↓H␈↓operational-denotational relationship.
␈↓ ↓H␈↓For␈α
example,␈α∞given␈α
a␈α∞LISP␈α
identifier␈α∞␈↓αx␈↓␈α
and␈α∞a␈α
member␈α∞of␈α
␈↓env␈↓,␈α∞say␈α
the␈α∞function␈α
␈↓{<x,2>,<y,4>}␈↓,
␈↓ ↓H␈↓then␈α␈↓λD␈↓␈αshould␈αmap␈α␈↓αx␈↓␈αonto␈α␈↓2␈↓.␈αThis␈αis␈αan␈αintuitive␈αway␈αof␈αsaying␈αthat␈α␈↓λD␈↓␈αshould␈αmap␈αa␈αmember␈αof
␈↓ ↓H␈↓<identifier>␈α∂onto␈α∂a␈α∂␈↓↓function␈↓.␈α∂This␈α∂function␈α∂will␈α⊂map␈α∂a␈α∂member␈α∂of␈α∂␈↓env␈↓␈α∂onto␈α∂an␈α∂element␈α⊂of␈α∂␈↓ S␈↓.
␈↓ ↓H␈↓Introducing ␈↓ i␈↓ as a meta-variable to range over <identifier>, then for ␈↓l ␈↓λε␈↓ env␈↓ we have:
␈↓ ↓H␈↓␈↓ ¬i␈↓λD␈↓∞(␈↓ i␈↓∞)␈↓(l)␈↓ = ␈↓l(i)␈↓
␈↓ ↓H␈↓The␈α␈↓↓denotation␈↓␈α
of␈αan␈α
identifier␈αis␈αa␈α
function;␈αwhereas␈α
the␈α␈↓↓value␈↓␈αof␈α
an␈αidentifier␈α
is␈αan␈α
element␈αof
␈↓ ↓H␈↓␈↓ S␈↓∪␈↓ Fn␈↓.
␈↓ ↓H␈↓The␈αtreatment␈αof␈αidentifiers␈αleads␈αdirectly␈α
into␈αthe␈αdenotional␈αaspects␈αof␈αfunction␈α
application.␈α We
␈↓ ↓H␈↓shall␈α
maintain␈α
the␈αparallels␈α
between␈α
evaluation␈αand␈α
denotation,␈α
by␈αgiving␈α
␈↓λD␈↓βe␈↓␈α
and␈α␈↓λD␈↓βa␈↓␈α
corresponding
␈↓ ↓H␈↓to␈α
␈↓αeval␈↓␈αand␈α
␈↓αapply␈↓.␈α Let␈α
␈↓ f␈↓␈αbe␈α
a␈αmember␈α
of␈α<function>␈α
and␈α␈↓ e␈↓␈α
be␈αa␈α
member␈αof␈α
<form>,␈αthen␈α
for␈αa
␈↓ ↓H␈↓given element of ␈↓env␈↓, ␈↓λD␈↓βa␈↓ maps ␈↓ f␈↓ onto an element of ␈↓ Fn␈↓, and ␈↓λD␈↓βe␈↓ maps ␈↓ e␈↓ onto an element of ␈↓ S␈↓.
␈↓ ↓H␈↓For example: ␈↓ ∧o␈↓λD␈↓βa␈↓∞(␈↓αcar␈↓∞)␈↓(l)␈↓ = ␈↓car␈↓ for all ␈↓l␈↓ in ␈↓env␈↓.
␈↓ ↓H␈↓Similar equations hold for the other LISP primitive functions and predicates. In general, then:
␈↓ ↓H␈↓␈↓ ¬`␈↓λD␈↓βa␈↓∞(␈↓ f␈↓∞)␈↓(l)␈↓ = ␈↓l(f)␈↓.
␈↓ ↓H␈↓To describe the evaluation of a function-call in LISP we must add an equation to ␈↓λD␈↓βe␈↓:
␈↓ ↓H␈↓␈↓ β(␈↓λD␈↓βe␈↓∞(␈↓ f␈↓[␈↓ e␈↓β1␈↓, ..., ␈↓ e␈↓βn␈↓]␈↓∞)␈↓(l)␈↓ = ␈↓λD␈↓βa␈↓∞(␈↓ f␈↓∞)␈↓(l)(␈↓λD␈↓βe␈↓∞(␈↓ e␈↓β1␈↓∞)␈↓(l)␈↓, ..., ␈↓λD␈↓βe␈↓∞(␈↓ e␈↓βn␈↓∞)␈↓(l))␈↓
␈↓ ↓H␈↓We␈α∀must␈α∀also␈α∀make␈α∀consistent␈α∀modifications␈α∀to␈α∀the␈α∀previous␈α∀clauses␈α∀of␈α∀␈↓λD␈↓βtgr␈↓␈α∀to␈α∀account␈α∀for
␈↓ ↓H␈↓environments.␈α
That␈α
is,␈α
the␈αvalue␈α
of␈α
a␈α
constant␈α
is␈αindependent␈α
of␈α
the␈α
specific␈α
environment␈αin␈α
which
␈↓ ↓H␈↓it is evaluated.
␈↓ ↓H␈↓␈↓ ¬¬␈↓λD␈↓βe␈↓∞(␈↓ s␈↓∞)␈↓(l)␈↓ = ␈↓s␈↓ for all ␈↓l␈↓ in ␈↓env␈↓.
␈↓ ↓H␈↓We must also extend our equations to account for conditional expressions.
␈↓ ↓H␈↓To␈α⊗discuss␈α↔function␈α⊗application␈α↔we␈α⊗must␈α↔give␈α⊗a␈α↔mathematical␈α⊗characterization␈α↔of␈α⊗function
␈↓ ↓H␈↓definitions.␈α⊃ In␈α⊃this␈α∩section␈α⊃we␈α⊃will␈α⊃handle␈α∩λ-notation␈α⊃without␈α⊃free␈α⊃variables,␈α∩postponing␈α⊃more
␈↓ ↓H␈↓complex cases to Section 4.11.
␈↓ ↓H␈↓Assuming␈α∞the␈α∞only␈α∞free␈α∞variables␈α∞in␈α∞␈↓λx␈↓␈α∞are␈α
among␈α∞the␈α∞␈↓αx␈↓βi␈↓'s,␈α∞the␈α∞denotation␈α∞of␈α∞␈↓αλ[[x␈↓β1␈↓α; ...; x␈↓βn␈↓α]␈α∞␈↓λx␈↓]␈α∞in␈α
a
␈↓ ↓H␈↓specified environment should be a function from ␈↓ S␈↓πn␈↓ to ␈↓ S␈↓ such that:
␈↓ ↓H␈↓␈↓ β(␈↓λD␈↓βa␈↓∞(␈↓αλ[[␈↓ v␈↓β1␈↓; ... ;␈↓ v␈↓βn␈↓] ␈↓ e␈↓]␈↓∞)␈↓(l)␈↓ = ␈↓␈↓λλ␈↓((x␈↓β1␈↓, ..., x␈↓βn␈↓) ␈↓λD␈↓βe␈↓∞(␈↓ e␈↓∞)␈↓(l : <x␈↓β1␈↓,v␈↓β1␈↓>, ..., <x␈↓βn␈↓,v␈↓βn␈↓>))␈↓
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 165␈↓
␈↓ ↓H␈↓where␈αλ␈αis␈α
the␈αLISP␈αλ-notation␈α
and␈α␈↓λλ␈↓␈αis␈α
its␈αmathematical␈αcounterpart␈↓π 118␈↓␈α
and␈α␈↓v␈↓βi␈↓␈αis␈αthe␈α
denotational
␈↓ ↓H␈↓counterpart of ␈↓ v␈↓βi␈↓, and ␈↓(l : ... )␈↓ means the environment ␈↓l␈↓ augmented with the explicitly given pairs.
␈↓ ↓H␈↓That␈α∩is,␈α∩␈↓(l : <x␈↓β1␈↓,v␈↓β1␈↓>, ..., <x␈↓βn␈↓,v␈↓βn␈↓>)␈↓␈α∩is␈α∪a␈α∩modification␈α∩of␈α∩␈↓l␈↓␈α∩such␈α∪that␈α∩each␈α∩␈↓v␈↓βi␈↓␈α∩is␈α∩bound␈α∪to␈α∩the
␈↓ ↓H␈↓corresponding ␈↓x␈↓βi␈↓:
␈↓ ↓H␈↓␈↓ αX␈↓(l : <x,v>)(v␈↓β1␈↓)␈↓ is:␈↓ ¬_␈↓if(␈↓ ¬Hv = ␈↓λB␈↓,
␈↓ ↓H␈↓␈↓ αX␈↓ ¬_␈↓ ¬H␈↓λB␈↓,
␈↓ ↓H␈↓␈↓ αX␈↓ ¬_␈↓ ¬Hif(␈↓ ¬xv␈↓β1␈↓ = ␈↓λB␈↓↓,
␈↓ ↓H␈↓↓␈↓ αX␈↓ ¬_␈↓ ¬H␈↓ ¬x␈↓λB␈↓,
␈↓ ↓H␈↓␈↓ αX␈↓ ¬_␈↓ ¬H␈↓ ¬xif(␈↓ ε(v␈↓β1␈↓ = x,
␈↓ ↓H␈↓␈↓ αX␈↓ ¬_␈↓ ¬H␈↓ ¬x␈↓ ε(v,
␈↓ ↓H␈↓␈↓ αX␈↓ ¬_␈↓ ¬H␈↓ ¬x␈↓ ε(l(v␈↓β1␈↓))))
␈↓ ↓H␈↓In more detail: ␈↓λλ␈↓((x␈↓β1␈↓, ... ,x␈↓βn␈↓) e(x␈↓β1␈↓, ... ,x␈↓βn␈↓)) ␈↓is a function ␈↓f␈↓: ␈↓[␈↓ S␈↓πn␈↓ → ␈↓ S␈↓]␈↓ such that:
␈↓ ↓H␈↓␈↓ β(is ␈↓e(t␈↓β1␈↓, ... ,t␈↓βn␈↓) ␈↓if m␈↓≥␈↓n and ␈↓∀␈↓i ␈↓t␈↓βi␈↓ ␈↓≠␈↓ ␈↓λB␈↓.␈↓π 119␈↓
␈↓ ↓H␈↓␈↓f(t␈↓β1␈↓, ..., t␈↓βm␈↓) ␈↓
␈↓ ↓H␈↓␈↓ β(is ␈↓λB␈↓ otherwise
␈↓ ↓H␈↓Given this basic outline, we can more accurately describe the "equation" of page 160:
␈↓ ↓H␈↓α␈↓ ¬αf[a␈↓β1␈↓α; ...; a␈↓βn␈↓α] = eval[(F A␈↓β1␈↓α ... A␈↓βn␈↓α)],
␈↓ ↓H␈↓Namely;
␈↓ ↓H␈↓␈↓λD␈↓βe␈↓∞(␈↓αeval[␈↓
R␈↓∞(␈↓ f␈↓α[␈↓ e␈↓β1␈↓α; ... ␈↓ e␈↓βn␈↓α]␈↓∞)␈↓α;␈↓
R␈↓∞(␈↓ a␈↓∞)␈↓α]␈↓∞)␈↓(l␈↓βinit␈↓)␈↓ = ␈↓λD␈↓βa␈↓∞(␈↓ f␈↓∞)␈↓(l␈↓βnew␈↓)(␈↓λD␈↓βe␈↓∞(␈↓ e␈↓β1␈↓∞)␈↓(l␈↓βnew␈↓), ..., ␈↓λD␈↓βe␈↓∞(␈↓ e␈↓βn␈↓∞)␈↓(l␈↓βnew␈↓))␈↓
␈↓ ↓H␈↓where ␈↓l␈↓βinit␈↓ is the initial symbol table and ␈↓l␈↓βnew␈↓ is ␈↓l␈↓βinit␈↓ augmented with the entires from ␈↓ a␈↓.
␈↓ ↓H␈↓One␈α⊃of␈α⊃the␈α⊃major␈α∩difficulties␈α⊃in␈α⊃supplying␈α⊃models␈α⊃for␈α∩applicative␈α⊃languages␈α⊃is␈α⊃caused␈α∩by␈α⊃the
␈↓ ↓H␈↓type-free␈α
requirement␈↓π 120␈↓.␈α
Self-application␈α
is␈αone␈α
indication␈α
of␈α
this.␈αWe␈α
can␈α
show␈α
that␈α
imposing␈αa
␈↓ ↓H␈↓type␈αstructure␈α
on␈αour␈αlanguage␈α
will␈αsolve␈αmany␈α
problems.␈αIn␈αa␈α
typed␈α␈↓λλ␈↓-calculus␈αan␈α
expression␈αwill
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 118␈↓␈α
We␈α
have␈α
written␈α
a␈α
␈↓λλ␈↓-expression␈α
with␈αmore␈α
than␈α
one␈α
formal␈α
parameter.␈α
This␈α
can␈α
be␈αjustified␈α
as
␈↓ ↓H␈↓an abbreviation: ␈↓λλ␈↓((x y) M) = ␈↓λλ␈↓((x) ␈↓λλ␈↓((y) M))␈↓.
␈↓ ↓H␈↓␈↓π 119␈↓␈α∩Note␈α⊃that␈α∩this␈α∩equation␈α⊃models␈α∩the␈α∩LISP␈α⊃trick␈α∩of␈α∩supplying␈α⊃too␈α∩many␈α∩arguments.␈α⊃Other
␈↓ ↓H␈↓anomalies␈α∞of␈α∞LISP,␈α∞including␈α∞dynamic␈α∞binding,␈α∞are␈α∞describable␈α∞using␈α∞these␈α∞techniques␈α∞([Gor 73],
␈↓ ↓H␈↓[Gor 75]).
␈↓ ↓H␈↓␈↓π 120␈↓␈α
It␈α
was␈α
not␈α
until␈α
1969␈α
that␈α
a␈α
model␈α
for␈α
the␈α
␈↓λλ␈↓-calculus␈α
was␈α
discovered␈α
even␈α
though␈α
the␈α
formalism
␈↓ ↓H␈↓was invented in the late 1930's.
␈↓ ↓H␈↓␈↓↓166 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓always␈α⊃have␈α⊃a␈α⊃normal␈α⊂form ([Mor 68]).␈α⊃Computationally␈α⊃this␈α⊃means␈α⊂that␈α⊃all␈α⊃the␈α⊃programs␈α⊂will
␈↓ ↓H␈↓terminate.␈α
Also,␈α
models␈αfor␈α
typed␈α
␈↓λλ␈↓-calculus␈α
are␈αmuch␈α
more␈α
readily␈α
attained ([Mil 73]).␈α However
␈↓ ↓H␈↓the␈α
type␈αfree␈α
calculus␈α
is␈αa␈α
stronger␈α
system,␈αand␈α
requiring␈αall␈α
expressions␈α
to␈αhave␈α
a␈α
consistent␈αtype
␈↓ ↓H␈↓structure␈α∞rules␈α∞out␈α∞several␈α∞useful␈α∞constructs;␈α∞in␈α∞particular,␈α∞the␈α∞␈↓λλ␈↓-calculus␈α∞counterpart␈α∞to␈α∞the␈α
LISP
␈↓ ↓H␈↓␈↓αlabel␈↓ operator cannot be consistently typed.
␈↓ ↓H␈↓From␈αthe␈αpractical␈αside,␈αa␈αtyped␈αstructure␈αis␈αa␈αmixed␈αblessing.␈α Language␈αdelarations␈αare␈αa␈αform␈αof
␈↓ ↓H␈↓typing␈αand␈αcan␈αbe␈αquite␈αhelpful␈αin␈αpinpointing␈αprogramming␈αerrors.␈αDeclarations␈αcan␈αalso␈αbe␈αused
␈↓ ↓H␈↓by␈α∂compilers␈α∂to␈α∂help␈α∂produce␈α∞optimized␈α∂code.␈α∂However,␈α∂a␈α∂type␈α∞structure␈α∂can␈α∂be␈α∂a␈α∂real␈α∞nuisance
␈↓ ↓H␈↓when␈α⊗trying␈α⊗to␈α⊗debug␈α⊗a␈α⊗program.␈α↔ It␈α⊗is␈α⊗frequently␈α⊗desirable␈α⊗to␈α⊗examine␈α⊗and␈α↔modify␈α⊗the
␈↓ ↓H␈↓representations␈α
of␈αabstract␈α
data␈α
structures.␈αThose␈α
kinds␈α
of␈αoperations␈α
imply␈α
the␈αability␈α
to␈αignore␈α
the
␈↓ ↓H␈↓type information.
␈↓ ↓H␈↓Logically,␈αthe␈αnext␈αaddition␈αto␈α␈↓εD␈↓␈αwould␈αinvolve␈αrecursion␈αand␈αfunction␈αdefinitions:␈α␈↓αlabel␈↓␈αand␈α"<=".
␈↓ ↓H␈↓We␈α
know␈α
that␈α
the␈α
LISP␈α
␈↓αlabel␈↓␈α
operator␈α∞is␈α
similar␈α
to␈α
"<=",␈α
but␈α
␈↓αlabel␈↓␈α
builds␈α
a␈α∞temporary␈α
definition,
␈↓ ↓H␈↓while␈α∞"<="␈α∞modifies␈α
the␈α∞global␈α∞environment.␈α∞Programming␈α
language␈α∞constructs␈α∞which␈α∞modify␈α
the
␈↓ ↓H␈↓environment␈α⊂are␈α⊂said␈α⊃to␈α⊂have␈α⊂␈↓↓side-effects␈↓␈α⊂and␈α⊃are␈α⊂an␈α⊂instance␈α⊂of␈α⊃what␈α⊂is␈α⊂called␈α⊃a␈α⊂imperative
␈↓ ↓H␈↓construct.␈α⊗ Since␈α⊗our␈α⊗main␈α⊗interest␈α⊗lies␈α⊗in␈α⊗the␈α⊗programming␈α⊗aspects,␈α⊗we␈α⊗will␈α⊗postpone␈α⊗the
␈↓ ↓H␈↓mathematics.␈α
The␈α
next␈α∞chapter␈α
introduces␈α
the␈α
procedural␈α∞aspects␈α
of␈α
imperative␈α
constructs␈α∞but␈α
in
␈↓ ↓H␈↓Section 4.11 we will investigate some of the mathematical aspects of "<=" and ␈↓αlabel␈↓.
␈↓ ↓H␈↓As␈α∀a␈α∃final␈α∀bridge␈α∀between␈α∃theory␈α∀and␈α∃practice␈α∀we␈α∀will␈α∃use␈α∀LISP␈α∀to␈α∃introduce␈α∀one␈α∃of␈α∀the
␈↓ ↓H␈↓fundamental␈αresults␈αin␈αrecursion␈αtheory:␈αa␈αproof␈αof␈αthe␈αnon-existence␈αof␈αan␈αalgorithm␈αto␈αdetermine
␈↓ ↓H␈↓whether␈αor␈α
not␈αa␈α
LISP␈αfunction␈αis␈α
total␈αThis␈α
is␈αalso␈αcalled␈α
the␈αunsolvability␈α
of␈αthe␈αhalting␈α
problem,
␈↓ ↓H␈↓since␈α
the␈α
existence␈αof␈α
such␈α
an␈α
algorithm␈αwould␈α
tells␈α
us␈α
whether␈αa␈α
LISP␈α
function␈α
would␈αterminate
␈↓ ↓H␈↓for all inputs␈↓π 121␈↓. That algorithm does not exist␈↓π 122␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 121␈↓␈α∪Again,␈α∪we␈α∪use␈α∪"LISP␈α∪function"␈α∪as␈α∪a␈α∪synonym␈α∪for␈α∪"algorithm".␈α∪To␈α∪complete␈α∀the␈α∪halting
␈↓ ↓H␈↓argument we must show that every algorithm is expressible in LISP.
␈↓ ↓H␈↓␈↓π 122␈↓ The argument is adapted from [Lev un].
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 167␈↓
␈↓ ↓H␈↓The proof depends on our knowledge about the function ␈↓αapply␈↓. The fundamental relationship is:
␈↓ ↓H␈↓␈↓ αhFor a function ␈↓αf␈↓ and arguments ␈↓αa␈↓β1␈↓, ... ,␈↓αa␈↓βn␈↓ we know that if
␈↓ ↓H␈↓␈↓ ¬#␈↓αf[a␈↓β1␈↓α; ... ;a␈↓βn␈↓α]␈↓ is defined then
␈↓ ↓H␈↓␈↓ βa␈↓αf[a␈↓β1␈↓α; ...;a␈↓βn␈↓α]␈↓ = ␈↓αapply[␈↓
R␈↓∞(␈↓αf␈↓∞)␈↓α;list[␈↓
R␈↓∞(␈↓αa␈↓β1␈↓∞)␈↓α; ... ;␈↓
R␈↓∞(␈↓αa␈↓βn␈↓∞)␈↓α];env]␈↓
␈↓ ↓H␈↓Compare␈α∪this␈α∪equation␈α∪with␈α∪the␈α∪equation␈α∪on␈α∪page 165.␈α∪ This␈α∪property␈α∪of␈α∪␈↓αapply␈↓␈α∪makes␈α∪it␈α∪a
␈↓ ↓H␈↓␈↓↓universal␈αfunction␈↓␈αfor␈αLISP␈αin␈αthe␈αsense␈αthat␈αif␈α
␈↓αapply␈↓␈αis␈αgiven␈αan␈αencoding␈αof␈αa␈αfunction,␈αof␈α
some
␈↓ ↓H␈↓arguments␈α⊃to␈α⊃be␈α⊃applied,␈α⊃and␈α⊃an␈α⊃environment␈α⊃which␈α⊃contains␈α⊃the␈α⊃definition␈α⊃of␈α⊃␈↓αf␈↓␈α⊃and␈α∩all␈α⊃the
␈↓ ↓H␈↓necessary subsidiary definitions needed by ␈↓αf␈↓, then ␈↓αapply␈↓ can simulate the behavior of ␈↓αf␈↓.
␈↓ ↓H␈↓We␈αwill␈αassume␈αthat␈αthe␈αrepresentation␈αof␈α␈↓αenv␈↓␈αis␈αthe␈αstandard␈αa-list␈αof␈αdotted␈α
pairs:␈αrepresentation
␈↓ ↓H␈↓of␈α∞name␈α
dotted␈α∞with␈α
representation␈α∞of␈α∞λ-expression.␈α
Given␈α∞a␈α
function␈α∞named␈α
␈↓αg␈↓,␈α∞together␈α∞with␈α
its
␈↓ ↓H␈↓λ-definition we will designate the S-expr representation of the dotted pair as ␈↓αg␈↓πR␈↓.
␈↓ ↓H␈↓For example, given
␈↓ ↓H␈↓␈↓ ∧@␈↓αfact <= λ[[x][x = 0 → 1;␈↓
t␈↓α → *[x;fact[x-1]]]];␈↓
␈↓ ↓H␈↓Then ␈↓αfact␈↓πR␈↓ is:
␈↓ ↓H␈↓α(FACT . (LAMBDA␈↓ βX(X)
␈↓ ↓H␈↓α␈↓ βX(COND␈↓ ∧H((ZEROP X) 1)
␈↓ ↓H␈↓α␈↓ βX␈↓ ∧H(T (TIMES X (FACT (SUB1 X))))))).␈↓
␈↓ ↓H␈↓Next, if ␈↓αf␈↓ refers to ␈↓αf␈↓β1␈↓ through ␈↓αf␈↓βn␈↓ in its evaluation, we will represent the environment as:
␈↓ ↓H␈↓α␈↓ ¬elist[f␈↓πR␈↓α;f␈↓β1␈↓πR␈↓α;... ;f␈↓βn␈↓πR␈↓α]
␈↓ ↓H␈↓Finally,␈α
we␈α
will␈α
identify␈α
such␈α
an␈α
environment␈α
structure␈α
as␈α
the␈α
representation␈α
of␈α
the␈α
definition␈αof␈α
the
␈↓ ↓H␈↓␈↓↓first␈↓␈α∪function␈α∩in␈α∪that␈α∩environment.␈α∪For␈α∪example,␈α∩a␈α∪complete␈α∩definition␈α∪of␈α∩␈↓αfact␈↓␈α∪would␈α∪be␈α∩an
␈↓ ↓H␈↓environment␈αbeginning␈αwith␈α␈↓αfact␈↓πR␈↓␈αand␈αfollowed␈αby␈α␈↓αzerop␈↓πR␈↓,␈α␈↓αtimes␈↓πR␈↓␈αor␈α␈↓αsub1␈↓πR␈↓␈αif␈αany␈αof␈αthose␈αfunctions
␈↓ ↓H␈↓were not considered primitive.
␈↓ ↓H␈↓Now assume the existence of a unary predicate ␈↓αtotal␈↓ such that:
␈↓ ↓H␈↓␈↓ αXgives ␈↓
t␈↓ if ␈↓αx␈↓ is a representation of a total unary␈↓π 123␈↓function.
␈↓ ↓H␈↓␈↓αtotal[x]␈↓
␈↓ ↓H␈↓␈↓ αXgives ␈↓
f␈↓ in all other cases.
␈↓ ↓H␈↓Notice␈α*that␈α*if␈α)␈↓αtotal[list[f␈↓πR␈↓α; ...]]␈↓␈α*is␈α*true,␈α)then␈α*for␈α*arbitrary␈α)␈↓αa␈↓␈α*we␈α*will␈α)have
␈↓ ↓H␈↓␈↓αapply[name[f␈↓πR␈↓α];list[a]; list[f␈↓πR␈↓α; ...]]␈↓ terminating and giving value ␈↓αf[a]␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 123␈↓␈α∀This␈α∪discussion␈α∀will␈α∪nominally␈α∀concern␈α∀unary␈α∪functions,␈α∀but␈α∪the␈α∀generalization␈α∀to␈α∪n-ary
␈↓ ↓H␈↓functions is immediate.
␈↓ ↓H␈↓␈↓↓168 Evaluation␈↓ )3.13␈↓
␈↓ ↓H␈↓Now we define a function:
␈↓ ↓H␈↓α␈↓ β%diag <= λ[[x][total[x] → list[apply[name[first[x]];list[x];x]]; ␈↓
t␈↓α → ␈↓
f␈↓α]].
␈↓ ↓H␈↓Note that ␈↓αdiag␈↓ is total. Now consider ␈↓αdiag␈↓πR␈↓:
␈↓ ↓H␈↓α(DIAG . (LAMBDA␈↓ βX(X)
␈↓ ↓H␈↓α␈↓ βX(COND␈↓ ∧H((TOTAL X) (LIST (APPLY (NAME (FIRST X))(LIST X) X)))
␈↓ ↓H␈↓α␈↓ βX␈↓ ∧H(T NIL))) )
␈↓ ↓H␈↓Finally,␈α∪form␈α∪␈↓αlist[diag␈↓πR␈↓α;␈α∩total␈↓πR␈↓α;␈α∪apply␈↓πR␈↓α;␈α∪...]␈↓.␈α∩Call␈α∪the␈α∪resulting␈α∩list␈α∪␈↓αdenv␈↓.␈α∪That␈α∩list␈α∪will␈α∪be␈α∩the
␈↓ ↓H␈↓representation of ␈↓αdiag␈↓ and all its necessary functions.
␈↓ ↓H␈↓Evaluate␈α␈↓αdiag[denv]␈↓.␈αSince␈α␈↓αdiag␈α␈↓↓is␈↓␈αtotal,␈αthen␈α␈↓αtotal[denv]␈↓␈αis␈αtrue,␈αand␈αwe␈αhave␈αreduced␈αthe␈αproblem
␈↓ ↓H␈↓to:
␈↓ ↓H␈↓α␈↓ ∧3list[apply[name[first[denv]];list[denv];denv]]
␈↓ ↓H␈↓but␈α*␈↓αname[first[denv]]␈α*=␈α*DIAG␈↓;␈α*and␈α*therefore␈α*the␈α*call␈α*on␈α*␈↓αapply␈↓␈α*reduces␈α)to
␈↓ ↓H␈↓␈↓αapply[DIAG;list[denv];denv]␈↓.␈α<But␈α<that's␈α<just␈α<␈↓αdiag[denv]␈↓,␈α<and␈α<we've␈α;shown
␈↓ ↓H␈↓␈↓αdiag[denv] = list[diag[denv]]␈↓.␈αThat's␈αjust␈α
not␈αpossible.␈αThus␈α
the␈αassumption␈αof␈α
the␈αexistence␈αof␈α
␈↓αtotal␈↓
␈↓ ↓H␈↓must be in error.
␈↓ ↓H␈↓The␈αusual␈αproof␈αof␈αthis␈αresult␈αis␈αgiven␈αin␈αnumber␈αtheory␈αand␈αinvolves␈αencoding␈αthe␈αfunctions␈αinto
␈↓ ↓H␈↓the␈αintegers␈α
and␈αthen␈α
expressing␈αthe␈αequivalent␈α
of␈αthe␈α
␈↓αapply␈↓␈αfunction␈αas␈α
an␈αalgorithm␈α
in␈αnumber
␈↓ ↓H␈↓theory.␈αThe␈αencoding␈αin␈αthe␈αintegers␈αis␈αanalogous␈αto␈αwhat␈α␈↓↓we␈↓␈αdid␈αin␈αencoding␈αin␈αthe␈αS-expressions.
␈↓ ↓H␈↓This␈α
is␈α
the␈α
problem␈α
of␈αrepresentation␈α
again.␈α
LISP␈α
␈↓↓is␈↓␈α
more␈αthan␈α
a␈α
programming␈α
language;␈α
it␈αis␈α
also
␈↓ ↓H␈↓a formalism for discussing computation.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Recall the problem on page 135, dealing with the following factorial algorithm:
␈↓ ↓H␈↓α␈↓ ¬
fact <= λ[[n] f[function[f]; n]]
␈↓ ↓H␈↓α␈↓ ∧@f <= λ[[g;n][n=0 → 1; ␈↓
t␈↓α → *[n; g[g; n-1]] ]]
␈↓ ↓H␈↓Rewrite ␈↓αfact␈↓ in terms a unary function ␈↓εt␈↓:
␈↓ ↓H␈↓␈↓ βq␈↓εt␈↓α <= λ[[x] function[λ[[n][n=0 → 1; ␈↓
t␈↓α → *[n; x[n-1]] ]]]]␈↓.
␈↓ ↓H␈↓Show that ␈↓αfact␈↓ = ␈↓εt␈↓α[fact]␈↓.
␈↓ ↓H␈↓␈↓↓3.13␈↓ λHReview and Reflection 169␈↓
␈↓ ↓H␈↓II.␈αThe␈αlanguage␈αdescribed␈αby␈αthe␈α␈↓εa␈↓␈αand␈α␈↓εb␈↓␈αrules␈αdoesn't␈αlook␈αparticularly␈αrich,␈αsimilar␈αin␈αpower␈αto
␈↓ ↓H␈↓LISP␈αwith␈αjust␈αfunction␈αapplication␈αbut␈αwithout␈αconditional␈αexpressions.␈α That␈αis␈αonly␈αan␈αillusion.
␈↓ ↓H␈↓Show␈αthat␈α
we␈αcan␈α
represent␈αa␈α
simple␈α␈↓αif␈↓␈α
function␈α␈↓αif[p;then;otherwise]␈↓.␈α
Hint:␈αshow␈α
that␈α␈↓λλ␈↓((x y) y)␈↓␈α
is
␈↓ ↓H␈↓a good representation for ␈↓
f␈↓ and ␈↓λλ␈↓((x y) x)␈↓ is a good representation for ␈↓
t␈↓.
␈↓ ↓H␈↓␈↓↓170 Imperative Constructs in LISP␈↓ @4.␈↓
␈↓ ↓H␈↓␈↓ ¬w␈↓↓CHAPTER 4
␈↓ ↓H␈↓↓␈↓ ∧=IMPERATIVE CONSTRUCTS IN LISP␈↓
␈↓ ↓H␈↓␈↓ ¬←␈↓↓4.1 Introduction␈↓
␈↓ ↓H␈↓All␈α⊗of␈α⊗the␈α⊗language␈α⊗constructs␈α⊗we␈α⊗have␈α⊗introduced␈α⊗so␈α⊗far␈α⊗are␈α⊗based␈α⊗on␈α↔a␈α⊗computational
␈↓ ↓H␈↓interpretation␈α∀of␈α∀function␈α∀application.␈α∃ We␈α∀therefore␈α∀call␈α∀the␈α∀language,␈α∃applicative␈α∀LISP␈↓π 124␈↓.
␈↓ ↓H␈↓Though␈α
the␈α
applicative␈α
subset␈α
of␈α
LISP␈α
is␈α
rich␈α
and␈α
powerful,␈α
it␈α
is␈α
often␈α
conveinent␈α
to␈α
have␈α
access␈α
to
␈↓ ↓H␈↓another type of language constuct called an ␈↓↓imperative␈↓.
␈↓ ↓H␈↓An␈αimperative␈αconstruct␈α
has␈αthe␈αintent␈α
of␈αa␈αcommand.␈α For␈α
that␈αreason␈αimperative␈α
commands␈αare
␈↓ ↓H␈↓called␈αstatements␈αrather␈αthan␈αexpressions␈αsince␈αit␈αis␈αthe␈α␈↓↓effect␈↓␈αof␈αthe␈αcommand␈αwhich␈αis␈αimportant;
␈↓ ↓H␈↓and␈α⊃its␈α⊃␈↓↓value␈↓,␈α⊃if␈α⊃it␈α⊃has␈α∩one,␈α⊃is␈α⊃of␈α⊃secondary␈α⊃importance␈↓π 125␈↓.␈α⊃ For␈α⊃example,␈α∩most␈α⊃programming
␈↓ ↓H␈↓languages␈α∞have␈α∂sequencing␈α∞commands:␈α∞"first␈α∂do␈α∞␈↓αS␈↓β1␈↓,␈α∞then␈α∂do␈α∞␈↓αS␈↓β2␈↓";␈α∞that␈α∂might␈α∞be␈α∂written␈α∞"␈↓αS␈↓β1␈↓α; S␈↓β2␈↓",
␈↓ ↓H␈↓where␈α␈↓αS␈↓β1␈↓␈αand␈α␈↓αS␈↓β2␈↓␈αare␈αstatements.␈α The␈αnature␈αof␈αimperatives␈αis␈αsomewhat␈αillusory,␈αsince␈αsequencing
␈↓ ↓H␈↓can be expressed in our applicative subset:
␈↓ ↓H␈↓α␈↓ ¬0S␈↓β1␈↓α;S␈↓β2␈↓ is ␈↓αλ[[] S␈↓β2␈↓α][S␈↓β1␈↓α]
␈↓ ↓H␈↓Here␈αwe␈αdepend␈αon␈αLISP's␈αcall␈αby␈αvalue␈αevaluation.␈α Since␈α␈↓αS␈↓β1␈↓␈αis␈αthe␈αargument,␈αit␈αis␈αevaluated␈α
first;
␈↓ ↓H␈↓then␈α∞␈↓αS␈↓β2␈↓␈α∞is␈α∞evaluated.␈α∂The␈α∞value␈α∞of␈α∞the␈α∂sequence␈α∞is␈α∞the␈α∞value␈α∂of␈α∞␈↓αS␈↓β2␈↓.␈α∞ LISP␈α∞calls␈α∂this␈α∞sequencing
␈↓ ↓H␈↓operation ␈↓αprog␈↓β2␈↓.
␈↓ ↓H␈↓An␈α
area␈α
which␈α
is␈α
thought␈α
to␈α
be␈α
the␈αprovince␈α
of␈α
imperatives␈α
is␈α
that␈α
of␈α
the␈α
assignment␈αstatement.␈α
We
␈↓ ↓H␈↓will␈α∪discuss␈α∪assignment␈α∪statements␈α∪further␈α∪in␈α∪Section 4.2,␈α∪but␈α∪the␈α∪intent␈α∪of␈α∪such␈α∪a␈α∩statement,
␈↓ ↓H␈↓written:
␈↓ ↓H␈↓␈↓ ¬≡<identifier> ← <expression>
␈↓ ↓H␈↓is␈αto␈α
think␈αof␈α
the␈α<identifier>␈α
as␈αa␈α
"box"␈αand␈α
the␈αintent␈α
of␈αthe␈α
assignment␈αis␈α
to␈αput␈α
the␈αvalue␈αof␈α
the
␈↓ ↓H␈↓<expression>␈αin␈α
the␈α"box".␈α
Yet,␈αfunction␈αapplication␈α
can␈αencompass␈α
many␈αof␈α
the␈αtraditional␈αuses␈α
of
␈↓ ↓H␈↓assignment.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 124␈↓ It is also referred to as "pure LISP".
␈↓ ↓H␈↓␈↓π 125␈↓␈α∞Some␈α∂programming␈α∞languages␈α∞insist␈α∂that␈α∞statements␈α∂do␈α∞␈↓↓not␈↓␈α∞have␈α∂value.␈α∞The␈α∂imperatives␈α∞of
␈↓ ↓H␈↓LISP ␈↓↓do␈↓ have values; they may be used or ignored as the programmer desires.
␈↓ ↓H␈↓␈↓↓4.1␈↓ OIntroduction 171␈↓
␈↓ ↓H␈↓Recall our definitions of ␈↓αlength␈↓ and ␈↓αlength␈↓β1␈↓:
␈↓ ↓H␈↓α␈↓ ∧⊂length[l] <= [null[l] → 0; ␈↓
t␈↓α → add1[length[rest[l]]]]
␈↓ ↓H␈↓α␈↓ ¬0length␈↓β1␈↓α[l] <= length␈↓λ'␈↓α[l;0]
␈↓ ↓H␈↓α␈↓ βblength␈↓λ'␈↓α[l1;c] <= [null[l1] → c; ␈↓
t␈↓α → length␈↓λ'␈↓α[rest[l1];add1[c]]]
␈↓ ↓H␈↓The␈α
variable␈α
␈↓αc␈↓␈α
is␈α
being␈αused␈α
as␈α
a␈α
"box"␈α
or␈α
"accumulator"␈α[Moor 74]␈α
to␈α
accumulate␈α
length␈α
of␈αthe␈α
list.
␈↓ ↓H␈↓We␈α⊗will␈α∃show␈α⊗in␈α∃Section 4.2␈α⊗that␈α∃␈↓αlength␈↓β1␈↓␈α⊗can␈α∃be␈α⊗translated␈α∃into␈α⊗a␈α∃program␈α⊗using␈α∃several
␈↓ ↓H␈↓imperative␈α∞features:␈α∞statements,␈α∂sequencing,␈α∞assignments,␈α∞and␈α∂an␈α∞imperative␈α∞control␈α∂regime␈α∞called
␈↓ ↓H␈↓␈↓↓iteration␈↓.␈α∩ We␈α⊃will␈α∩study␈α⊃iterative␈α∩control␈α⊃in␈α∩Section 4.2␈α⊃and␈α∩Section 4.3␈α⊃but␈α∩it␈α⊃can␈α∩be␈α⊃shown
␈↓ ↓H␈↓that iterative control can be translated into recursive control ([McC 60], [Sam 75]).
␈↓ ↓H␈↓In␈α∩many␈α∩instances␈α∩the␈α∩most␈α∩important␈α∩implication␈α∩of␈α∩imperatives␈α∩is␈α∩"convenience".␈α∪There␈α∩are
␈↓ ↓H␈↓algorithms␈α∞which␈α∞are␈α∞most␈α∞naturally␈α∞described␈α∞in␈α∞terms␈α∞of␈α∞sequences␈α∞of␈α∞statements␈α∞and␈α∞iteration;
␈↓ ↓H␈↓and␈α∪there␈α∪are␈α∪many␈α∩lessons␈α∪to␈α∪be␈α∪learned␈α∪by␈α∩careful␈α∪analysis␈α∪of␈α∪natural␈α∪implementations␈α∩of
␈↓ ↓H␈↓imperative␈α∂constructs.␈α∂We␈α∂are␈α⊂not␈α∂looking␈α∂for␈α∂a␈α∂minimal␈α⊂language,␈α∂we␈α∂are␈α∂looking␈α∂for␈α⊂a␈α∂useful
␈↓ ↓H␈↓programming␈αtool.␈α One␈αof␈αthe␈αmost␈αuseful␈αplaces␈αfor␈αimperative␈αconstructs␈αis␈αin␈αarea␈αof␈αnon-local
␈↓ ↓H␈↓variables,␈α⊃using␈α∩assignment␈α⊃statements␈α∩to␈α⊃pass␈α⊃information␈α∩across␈α⊃applicative␈α∩boundaries.␈α⊃This
␈↓ ↓H␈↓technique␈α⊂is␈α⊃called␈α⊂using␈α⊃side-effects.␈α⊂It␈α⊂may␈α⊃very␈α⊂well␈α⊃be␈α⊂that␈α⊂the␈α⊃most␈α⊂distinctive␈α⊃features␈α⊂of
␈↓ ↓H␈↓imperative constructs are involved with their side-effect aspects.
␈↓ ↓H␈↓For␈αexample,␈αLISP␈αimplementations␈α
include␈αa␈αunary␈αprimitive␈αnamed␈α
␈↓αprint␈↓␈αwhose␈αeffect␈αis␈αto␈α
print
␈↓ ↓H␈↓the␈α∞value␈α∞of␈α∞its␈α∂argument␈α∞on␈α∞the␈α∞current␈α∞output␈α∂device.␈α∞This␈α∞function␈α∞also␈α∞returns␈α∂its␈α∞evaluated
␈↓ ↓H␈↓argument␈α⊂as␈α⊂the␈α⊂value␈α⊂of␈α⊂the␈α⊂␈↓αprint␈↓␈α⊂statement.␈α⊂Thus␈α⊂mathematically,␈α⊂␈↓αprint␈↓␈α⊂acts␈α⊂like␈α⊂an␈α⊂identity
␈↓ ↓H␈↓function, but its execution certainly affects the programmer's environment␈↓π 126␈↓.
␈↓ ↓H␈↓Side-effects␈α
can␈α
also␈α
spoil␈α
some␈α
of␈α
the␈α
theoretical␈α
properties␈α
of␈α
languages.␈α
In␈α
our␈α
earlier␈α
discussions,
␈↓ ↓H␈↓we␈α∩have␈α∩implied␈α∩that␈α∩call-by-value␈α∩is␈α∩a␈α⊃subset␈α∩of␈α∩call-by-name␈α∩in␈α∩the␈α∩sense␈α∩that␈α∩whenever␈α⊃a
␈↓ ↓H␈↓call-by-value␈α∞computation␈α∞terminates,␈α∞the␈α∞corresponding␈α∞call-by-name␈α∞computation␈α∞will␈α∞as␈α∞well.␈α
In
␈↓ ↓H␈↓the presence of side-effects, this is ␈↓↓not␈↓ true. We give an example on page 213.
␈↓ ↓H␈↓␈↓ ¬C␈↓↓4.2 The ␈↓αprog␈↓↓-feature␈↓α
␈↓ ↓H␈↓Though␈αrecursion␈αis␈αa␈α
significant␈αtool␈αfor␈αconstructing␈α
LISP␈αprograms,␈αthere␈αis␈α
another␈αtechnique
␈↓ ↓H␈↓for␈α
defining␈α
algorithms␈α
in␈αLISP.␈α
It␈α
is␈α
an␈αiterative␈α
style␈α
of␈α
programming␈αwhich␈α
is␈α
called␈α
the␈α␈↓αprog␈↓␈α
or
␈↓ ↓H␈↓␈↓αprog␈↓ram feature.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 126␈↓␈α
Whether␈α
the␈αact␈α
of␈α
printing␈α
is␈αa␈α
side-effect␈α
or␈α
the␈αfact␈α
that␈α
␈↓αprint␈↓␈α
returns␈αa␈α
value␈α
is␈αa␈α
side-effect
␈↓ ↓H␈↓depends on your point of view.
␈↓ ↓H␈↓␈↓↓172 Imperative Constructs in LISP␈↓ 24.2␈↓
␈↓ ↓H␈↓Many␈α∂algorithms␈α∂are␈α∂presented␈α∂more␈α∂naturally␈α∂as␈α∂iterative␈α∂schemes.␈α∂ For␈α∂example,␈α∂the␈α∂recursive
␈↓ ↓H␈↓algorithms␈α∂␈↓αlength␈↓␈α∞and␈α∂␈↓αlength␈↓β1␈↓,␈α∂given␈α∞on␈α∂page 171,␈α∂compute␈α∞the␈α∂length␈α∂of␈α∞a␈α∂list.␈α∂ Compare␈α∞those
␈↓ ↓H␈↓schemes with the following:
␈↓ ↓H␈↓␈↓↓1.␈↓ Set a variable ␈↓αl1␈↓ to the given list. Set a variable ␈↓αc␈↓ to zero.
␈↓ ↓H␈↓␈↓↓2.␈↓ If the list is empty, return the current value in ␈↓αc␈↓ as value of the computation.
␈↓ ↓H␈↓␈↓↓3.␈↓ Otherwise, increment ␈↓αc␈↓ by one.
␈↓ ↓H␈↓␈↓↓4.␈↓ Set ␈↓αl1␈↓ to the ␈↓αrest␈↓ of ␈↓αl1␈↓.
␈↓ ↓H␈↓␈↓↓5.␈↓ Go to line 2.
␈↓ ↓H␈↓Here is a LISP version of the algorithm:
␈↓ ↓H␈↓αlength <= λ[[l]prog[[l1;c]
␈↓ ↓H␈↓α␈↓ β(␈↓ βHl1 ← l;
␈↓ ↓H␈↓α␈↓ β(␈↓ βHc ← 0;
␈↓ ↓H␈↓α␈↓ β(a␈↓ βH[null[l1] → return[c]];
␈↓ ↓H␈↓α␈↓ β(␈↓ βHc ← c+1;
␈↓ ↓H␈↓α␈↓ β(␈↓ βHl1 ← rest[l1];
␈↓ ↓H␈↓α␈↓ β(␈↓ βHgo[a]] ]
␈↓ ↓H␈↓We␈α↔have␈α⊗introduced␈α↔several␈α⊗new␈α↔symbols,␈α↔formats,␈α⊗and␈α↔functions␈α⊗in␈α↔this␈α↔example.␈α⊗These
␈↓ ↓H␈↓innovations␈αmust␈αbe␈αexplained␈αbefore␈αthe␈αexample␈αis␈αcomplete.␈αFirst,␈αthe␈αbasic␈αsyntax␈αof␈αa␈α␈↓αprog␈↓␈αis
␈↓ ↓H␈↓given by:
␈↓ ↓H␈↓<prog>␈↓ β(::= ␈↓αprog␈↓[[<prog variables>]<prog body>]
␈↓ ↓H␈↓<prog body>␈↓ β(::= <prog element><prog body> | <prog element>
␈↓ ↓H␈↓<prog element>␈↓ β(::= <label> | <prog form>;
␈↓ ↓H␈↓<label>␈↓ β(::= <identifier>
␈↓ ↓H␈↓<prog form>␈↓ β(::= <application>
␈↓ ↓H␈↓␈↓ β(::= <conditional statement>
␈↓ ↓H␈↓␈↓ β(::= <assignment statement>
␈↓ ↓H␈↓␈↓ β(::= <return statement>
␈↓ ↓H␈↓␈↓ β(::= <go statement>
␈↓ ↓H␈↓<conditional statement>␈↓ ∧(::= <conditional expression>
␈↓ ↓H␈↓<assignment statement>␈↓ ∧(::= <identifier> ← <form>
␈↓ ↓H␈↓<return statement>␈↓ ∧(::= ␈↓αreturn␈↓[<form>]
␈↓ ↓H␈↓<go statement>␈↓ β(␈↓ ∧(::= ␈↓αgo␈↓[<form>]
␈↓ ↓H␈↓In␈α
the␈α
example,␈α
the␈α
variables,␈α
␈↓αl1␈↓␈α
and␈α
␈↓αc␈↓,␈α
are␈α
called␈α
␈↓αprog␈↓ variables.␈α
They␈α
are␈α
local␈α
variables,␈α
acting
␈↓ ↓H␈↓␈↓↓4.2␈↓ →The ␈↓αprog␈↓↓-feature 173␈↓α
␈↓ ↓H␈↓like␈α⊃λ-variables;␈α⊃as␈α⊃a␈α⊂result,␈α⊃␈↓αprog␈↓s␈α⊃can␈α⊃be␈α⊃used␈α⊂recursively.␈α⊃ In␈α⊃most␈α⊃implementations␈α⊃the␈α⊂␈↓αprog␈↓
␈↓ ↓H␈↓variables are initialized to ␈↓α( )␈↓ and we will assume this convention throughout the text␈↓π 127␈↓.
␈↓ ↓H␈↓The␈α␈↓αprog␈↓␈αbody␈α
is␈αa␈αsequence␈αof␈α
␈↓αprog␈↓ forms␈αand␈αlabels.␈α Each␈α
␈↓αprog␈↓ form␈αis␈αevaluated␈αin␈α
the␈αusual
␈↓ ↓H␈↓LISP␈α
manner,␈α
and␈α
since␈α
the␈α
␈↓αprog␈↓ body␈α
can␈α∞consist␈α
of␈α
a␈α
sequence␈α
of␈α
␈↓αprog␈↓ forms,␈α
the␈α∞␈↓αprog␈↓-body␈α
is
␈↓ ↓H␈↓evaluated from left-to-right.
␈↓ ↓H␈↓If␈α
the␈α∞intent␈α
of␈α∞the␈α
␈↓αprog␈↓␈α∞was␈α
simply␈α
to␈α∞execute␈α
the␈α∞sequence␈α
of␈α∞␈↓αprog␈↓ forms,␈α
in␈α∞left-to-right␈α
order,
␈↓ ↓H␈↓then ␈↓αprog␈↓ could be replaced by a much simpler construct like ␈↓αprogn␈↓:
␈↓ ↓H␈↓α␈↓ ¬+progn <= λ[[x␈↓β1␈↓α; ...; x␈↓βn␈↓α] x␈↓βn␈↓α]
␈↓ ↓H␈↓However␈αwe␈αwill␈αadd␈αconstructs␈αto␈αLISP␈αwhich␈αwill␈αallow␈αus␈αto␈αvary␈αthe␈αflow␈αof␈αcontrol␈αwithin␈αthe
␈↓ ↓H␈↓␈↓αprog␈↓ body.␈αIt␈αis␈αto␈αthis␈αend␈αthat␈αwe␈αuse␈αlabels,␈αlike␈α␈↓αa␈↓␈αin␈αthe␈αexample␈↓π 128␈↓.␈αBefore␈αwe␈αdiscuss␈αcontrol
␈↓ ↓H␈↓structures, we give more details on LISP's assignment statement.
␈↓ ↓H␈↓As␈α⊂with␈α⊂all␈α⊂LISP␈α⊂constructs,␈α⊂the␈α⊂assignment␈α⊂statement␈α⊂returns␈α⊂a␈α⊂value,␈α⊂but␈α⊂we␈α⊂identify␈α⊂it␈α⊂as␈α⊂a
␈↓ ↓H␈↓statement␈α
since␈α
it␈α
is␈α
executed␈α
more␈α
for␈α
effect␈α
than␈α
for␈α
value.␈α
The␈α
value␈α
of␈α
the␈α
assignment␈α
is␈αthe
␈↓ ↓H␈↓value␈αof␈αthe␈αform␈αon␈α
its␈αright-hand-side.␈α In␈αour␈αexample␈αof␈α
␈↓αlength␈↓,␈αwe␈αused␈αan␈αassignment␈αto␈α
bind
␈↓ ↓H␈↓␈↓αl1␈↓␈αto␈α
the␈αvalue␈αof␈α
␈↓αl␈↓␈αand␈α
to␈αbind␈α␈↓αc␈↓␈α
to␈α␈↓α0␈↓.␈α To␈α
evaluate␈αan␈α
assignment,␈αwe␈αfirst␈α
evaluate␈αthe␈αform;␈α
then
␈↓ ↓H␈↓the␈α⊂identifier␈α⊂is␈α⊂located␈α⊂by␈α⊂searching␈α⊂the␈α⊃access␈α⊂chain.␈α⊂Thus␈α⊂the␈α⊂identifier␈α⊂may␈α⊂be␈α⊃a␈α⊂non-local
␈↓ ↓H␈↓variable.␈α∂When␈α∂the␈α⊂identifier␈α∂is␈α∂located␈α∂its␈α⊂current␈α∂value␈α∂is␈α∂replaced␈α⊂by␈α∂the␈α∂value␈α∂of␈α⊂the␈α∂form.
␈↓ ↓H␈↓Notice␈α
that␈α
this␈α
is␈α
a␈α
different␈α
kind␈α
of␈α
binding␈α
than␈α
that␈α
previously␈α
done␈α
by␈α
λ-binding.␈αIn␈α
λ-binding
␈↓ ↓H␈↓we␈αalways␈αassociated␈α
a␈αnew␈αvalue␈α
with␈αa␈αnewly␈αcreated␈α
local␈αsymbol␈αtable␈α
as␈αwe␈αentered␈αthe␈α
λ-body.
␈↓ ↓H␈↓We␈αnever␈αdestroyed␈αthe␈αold␈αbinding␈αof␈αa␈αvariable.␈αThe␈αassigment␈αstatement␈αinvolves␈αa␈αdestructive
␈↓ ↓H␈↓change␈α
to␈α
the␈α
binding.␈α
This␈α
is␈α
important␈αsince␈α
assignments␈α
to␈α
non-local␈α
variables␈α
can␈α
have␈αeffect
␈↓ ↓H␈↓outside␈α
the␈α
␈↓αprog␈↓␈α
while␈α
a␈α
λ-rebinding␈α
cannot.␈α∞This␈α
is␈α
how␈α
an␈α
assignment␈α
statement␈α
can␈α∞achieve␈α
a
␈↓ ↓H␈↓more permanent side-effect.
␈↓ ↓H␈↓As␈α
we␈α
intimated␈α
earlier,␈α␈↓αprog␈↓␈α
introduces␈α
some␈α
new␈α
control␈αstructures␈α
so␈α
that␈α
the␈α
␈↓αprog␈↓ body␈αneed␈α
not
␈↓ ↓H␈↓be␈αexecuted␈αin␈αsimple␈αleft-to-right␈αorder.␈α The␈αcontrol␈αstructures␈αare:␈αthe␈αconditional␈αstatement,␈αthe
␈↓ ↓H␈↓␈↓αreturn␈↓ statement, and the ␈↓αgo␈↓ statement.
␈↓ ↓H␈↓Though␈α⊂conditional␈α⊂statements␈α⊂in␈α⊂␈↓αprog␈↓s␈α⊂have␈α∂the␈α⊂same␈α⊂syntax␈α⊂as␈α⊂conditional␈α⊂expressions,␈α∂their
␈↓ ↓H␈↓semantics␈αis␈αslightly␈αdifferent.␈αA␈αconditional␈αstatement␈αis␈αexecuted␈αin␈αthe␈αusual␈αmanner␈αunless␈αnone
␈↓ ↓H␈↓of␈α
the␈α∞predicate␈α
alternatives␈α∞is␈α
satisfied.␈α∞Recall␈α
that␈α
a␈α∞conditional␈α
expression␈α∞is␈α
undefined␈α∞in␈α
this
␈↓ ↓H␈↓case;␈αa␈αconditional␈αstatement␈αhowever␈αis␈αdefined,␈αreturns␈α␈↓α( )␈↓,␈αand␈αexecutes␈αthe␈αnext␈αstatement␈αin␈α
the
␈↓ ↓H␈↓␈↓αprog␈↓ body.␈α
In␈α
our␈α
␈↓αlength␈↓␈α
example,␈α
the␈α
expression,␈α
␈↓α[null[l1] → return[c]]␈↓ ␈α
indicates␈α
that␈α
if␈α∞␈↓αl1␈↓␈α
is
␈↓ ↓H␈↓not␈α
empty␈α
the␈α
␈↓αprog␈↓ body␈α
continues␈αat␈α
the␈α
next␈α
statement␈α
with␈αthe␈α
assignment␈α
of␈α
␈↓αrest[l1]␈↓␈α
to␈α
␈↓αl1␈↓;␈αthe
␈↓ ↓H␈↓assignment destroys the old value of ␈↓αl1␈↓. If ␈↓αl1␈↓ ␈↓↓is␈↓ empty, then the statement ␈↓αreturn[c]␈↓ is executed.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 127␈↓␈αA␈αuseful␈αalternative␈αis␈αto␈αinitialize␈αthem␈αto␈αsome␈α"unbound"␈αvalue.␈αIn␈αthat␈αway␈αthe␈αsystem␈αcan
␈↓ ↓H␈↓recognize attempts to select the value of a ␈↓αprog␈↓ variable before is has been assigned to.
␈↓ ↓H␈↓␈↓π 128␈↓ Labels are also known as "tags".
␈↓ ↓H␈↓␈↓↓174 Imperative Constructs in LISP␈↓ 24.2␈↓
␈↓ ↓H␈↓There␈αis␈α
a␈αuseful␈α
interplay␈αbetween␈αthe␈α
λ-binding␈αof␈α
␈↓αl␈↓␈αand␈αthe␈α
assignment␈αbinding␈α
of␈α␈↓αl1␈↓.␈α We␈α
could
␈↓ ↓H␈↓have␈α∀dispensed␈α∃with␈α∀the␈α∀␈↓αprog␈↓ variable␈α∃␈↓αl1␈↓,␈α∀and␈α∃used␈α∀␈↓αl␈↓␈α∀throughout␈α∃the␈α∀␈↓αprog␈↓ body.␈α∃Even␈α∀the
␈↓ ↓H␈↓assignment␈α⊂␈↓αl ← rest[l]␈↓␈α⊃would␈α⊂not␈α⊃have␈α⊂effected␈α⊃the␈α⊂binding␈α⊃of␈α⊂the␈α⊃original␈α⊂argument␈α⊃passed␈α⊂to
␈↓ ↓H␈↓␈↓αlength␈↓.␈αThis␈αis␈α
assured␈αbecause␈αthe␈α
λ-binding␈αsaves␈αthat␈α
value␈αand␈αthe␈α
effect␈αof␈αthe␈α
assignment␈αis
␈↓ ↓H␈↓only␈α
to␈αchange␈α
the␈α
contents␈αof␈α
a␈α"box"␈α
whose␈α
current␈αcontent␈α
is␈αa␈α
"pointer"␈α
to␈αthe␈α
value.␈α
None␈αof
␈↓ ↓H␈↓the␈α⊂LISP␈α⊂operations␈α∂we␈α⊂have␈α⊂discussed␈α⊂can␈α∂alter␈α⊂a␈α⊂value␈α⊂"pointed to"␈α∂in␈α⊂this␈α⊂fashion.␈α⊂We␈α∂will
␈↓ ↓H␈↓discuss such operations in Section 7.6.
␈↓ ↓H␈↓The␈α∞␈↓αreturn␈↓␈α∞statement␈α∞is␈α∞a␈α∞␈↓αprog␈↓␈α∞construct␈α∞similar␈α
in␈α∞effect␈α∞to␈α∞exiting␈α∞a␈α∞λ-expression.␈α∞It␈α∞is␈α∞used␈α
to
␈↓ ↓H␈↓leave␈αa␈α
␈↓αprog␈↓ body␈αand␈α
return␈αto␈αthe␈α
caller␈αof␈α
the␈α␈↓αprog␈↓.␈α
As␈αwe␈αleave␈α
the␈α␈↓αprog␈↓,␈α
the␈αbindings␈α
of␈αthe
␈↓ ↓H␈↓␈↓αprog␈↓ variables␈αare␈αremoved␈αas␈αare␈αany␈αλ-bindings␈αmade␈αon␈αentry␈αto␈αthe␈α␈↓αprog␈↓.␈α The␈αvalue␈αreturned
␈↓ ↓H␈↓is␈α
the␈α
value␈α
of␈α
the␈α
argument␈α
to␈α
the␈α
␈↓αreturn␈↓␈α
statement.␈α
The␈α
␈↓αreturn␈↓␈α
statement␈α
may␈α
be␈α
nested␈α
within
␈↓ ↓H␈↓other LISP computation, as for example:
␈↓ ↓H␈↓α␈↓ ¬4concat[A;return[list[B]]].
␈↓ ↓H␈↓The␈α∞effect␈α∞of␈α∞the␈α∞␈↓αreturn␈↓␈α∞is␈α∞immediate;␈α∂the␈α∞␈↓αconcat␈↓␈α∞would␈α∞never␈α∞complete␈α∞its␈α∞operation.␈α∂We␈α∞would
␈↓ ↓H␈↓return␈α␈↓α(B)␈↓␈αto␈αthe␈αcaller␈αof␈αthe␈αenclosing␈α␈↓αprog␈↓.␈αA␈αbit␈αof␈αcare␈αis␈αneeded␈αin␈αdescribing␈αthe␈αmeaning␈αof
␈↓ ↓H␈↓␈↓αreturn␈↓:␈α∂we␈α∂look␈α∂for␈α∂the␈α∂latest␈α∂instance␈α∂of␈α∂an␈α∂entrance␈α∂to␈α∂a␈α∂␈↓αprog␈↓␈α∂and␈α∂return␈α∂from␈α∂that␈α∂␈↓αprog␈↓.␈α∞To
␈↓ ↓H␈↓visualize␈α⊃this,␈α⊃we␈α⊃use␈α⊃the␈α⊂Weizenbaum␈α⊃environments (page 128).␈α⊃We␈α⊃search␈α⊃the␈α⊃␈↓↓control␈α⊂chain␈↓,
␈↓ ↓H␈↓looking␈α
for␈α
the␈α
first␈α
␈↓ Form␈↓␈α
which␈α
is␈α
␈↓αprog[[ ... ] ... ]␈↓.␈α
We␈α
then␈α
restore␈α
using␈α
the␈α
access␈α
and␈α
control
␈↓ ↓H␈↓information␈αfound␈αin␈αthat␈αdiagram.␈α We␈αwill␈α
give␈αa␈αcomprehensive␈αexample␈αafter␈αdiscussing␈αthe␈α
␈↓αgo␈↓
␈↓ ↓H␈↓statement.
␈↓ ↓H␈↓The␈α␈↓αgo␈↓␈αstatement␈αis␈αused␈αin␈αconjunction␈αwith␈αlabels␈αto␈αdivert␈αthe␈αimplied␈αleft-to-right␈αexecution␈αof
␈↓ ↓H␈↓the␈α␈↓αprog␈↓ body.␈α Labels␈αreally␈αaren't␈αexecuted;␈αthey␈αare␈αused␈αto␈αname␈αstatements␈αin␈αa␈α␈↓αprog␈↓.␈α It␈αis␈αthe
␈↓ ↓H␈↓␈↓αgo␈↓␈α⊂statement␈α⊃which␈α⊂uses␈α⊃the␈α⊂label␈α⊃as␈α⊂a␈α⊃destination␈α⊂for␈α⊃transferring␈α⊂control.␈α⊃ Labels␈α⊂may␈α⊃be␈α⊂in
␈↓ ↓H␈↓conflict␈α
with␈αthe␈α
λ-variables␈α
or␈α␈↓αprog␈↓ variables␈α
since␈α
the␈αevaluator␈α
for␈α
␈↓αprog␈↓s␈αcan␈α
resolve␈αthe␈α
conflicts
␈↓ ↓H␈↓by␈αcontext.␈αAny␈αidentifier␈αoccurring␈αby␈αitself␈αin␈αa␈α␈↓αprog␈↓ body␈αis␈αa␈αlabel.␈αAny␈αidentifier␈αoccurring␈αin
␈↓ ↓H␈↓an␈α
application␈α
other␈α
than␈α
a␈α∞␈↓αgo␈↓ statement␈α
is␈α
a␈α
variable␈α
and␈α
its␈α∞value␈α
is␈α
searched␈α
for␈α
in␈α∞the␈α
access
␈↓ ↓H␈↓chain,␈αwhereas␈αan␈αidentifier␈αappearing␈αin␈αa␈α␈↓αgo␈↓␈αstatement␈αis␈αinterpreted␈αas␈αa␈αlabel␈αand␈αsearched␈αfor
␈↓ ↓H␈↓in a ␈↓αprog␈↓ body.
␈↓ ↓H␈↓The␈α
␈↓αgo␈↓␈α
statement␈αis␈α
a␈α
little␈α
more␈αcomplicated␈α
than␈α
the␈α␈↓αreturn␈↓␈α
statement.␈α
If␈α
the␈αargument␈α
to␈α
␈↓αgo␈↓␈αis␈α
an
␈↓ ↓H␈↓identifier␈α
then␈α
it␈αis␈α
interpreted␈α
as␈αa␈α
label;␈α
otherwise,␈α
the␈αargument␈α
is␈α
␈↓↓evaluated␈↓␈αand␈α
the␈α
result␈αof␈α
the
␈↓ ↓H␈↓evaluation␈αexamined.␈α This␈αprocess␈αcontinues␈αuntil␈αa␈αlabel␈αhas␈αbeen␈αuncovered␈αas␈αthe␈αresult␈α
of␈αan
␈↓ ↓H␈↓evaluation.␈α At␈αthat␈αtime␈αwe␈αmust␈αlocate␈αa␈αstatment␈αin␈αa␈α␈↓αprog␈↓␈αwhich␈αhas␈αa␈αmatching␈αlabel␈αattached
␈↓ ↓H␈↓to␈α∂it.␈α∂Our␈α∂intention␈α∂is␈α∂to␈α∂transfer␈α⊂control␈α∂to␈α∂that␈α∂statement.␈α∂ We␈α∂locate␈α∂the␈α∂labeled␈α⊂statement␈α∂as
␈↓ ↓H␈↓follows:␈α
we␈α
look␈α∞through␈α
the␈α
control␈α∞chain␈α
for␈α
the␈α∞first␈α
␈↓αprog␈↓␈α
which␈α∞contains␈α
the␈α
label.␈α∞When␈α
the
␈↓ ↓H␈↓label␈α∪is␈α∩found␈α∪we␈α∩transfer␈α∪control␈α∪to␈α∩that␈α∪labeled␈α∩statement,␈α∪restoring␈α∩the␈α∪access␈α∪and␈α∩control
␈↓ ↓H␈↓environments␈αof␈α
the␈α␈↓αprog␈↓␈αwhich␈α
contain␈αthat␈α
statement.␈αThus␈αthere␈α
is␈αa␈α
double␈αsearch␈αinvolved:␈α
we
␈↓ ↓H␈↓search␈αthe␈αcontrol␈αchain␈αfor␈α␈↓αprog␈↓␈αforms,␈αand␈αsearch␈αthe␈α␈↓αprog␈↓␈αforms␈αfor␈αthe␈αlabel.␈α Labels␈αneed␈αnot
␈↓ ↓H␈↓be local; we find the closest dynamically surrounding ␈↓αprog␈↓ which contains the required label.
␈↓ ↓H␈↓The␈α
non-local␈α
␈↓αgo␈↓␈α
and␈α
␈↓αreturn␈↓␈α
differ␈α
from␈α
the␈α
usual␈α
procedure␈α
exit␈α
in␈α
that␈α
they␈α
do␈α
not␈α
restore␈α
the
␈↓ ↓H␈↓enclosing control environment, but escape further back the control chain.
␈↓ ↓H␈↓␈↓↓4.2␈↓ →The ␈↓αprog␈↓↓-feature 175␈↓α
␈↓ ↓H␈↓Finally, as an example covering the new features of ␈↓αprog␈↓ consider:
␈↓ ↓H␈↓α␈↓ βxf <= λ[[y;z] prog[[l;x]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬H␈↓ ¬hl ← 2;
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬Hl␈↓ ¬hu ← g[y;x;z]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬H␈↓ ¬h ... ]]
␈↓ ↓H␈↓α␈↓ βxg <= λ[[x;y;z] prog[[ ]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬H␈↓ ¬h ...
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬H␈↓ ¬hgo[l]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬H␈↓ ¬h ...
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬H␈↓ ¬hreturn[first[x]]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬H␈↓ ¬h ... ]]
␈↓ ↓H␈↓In␈α␈↓αf␈↓,␈α␈↓αl␈↓␈αis␈αboth␈αa␈αlabel␈αand␈αa␈α␈↓αprog␈↓ variable.␈α Notice␈αin␈α␈↓αg␈↓␈αthat␈αwe␈αhave␈αno␈α␈↓αprog␈↓␈αvariables;␈αand␈αsince
␈↓ ↓H␈↓we assume that ␈↓αl␈↓ is not a label in ␈↓αg␈↓ we have a non-local ␈↓αgo␈↓.
␈↓ ↓H␈↓Consider the evaluation of ␈↓αf[(A B);3]␈↓.
␈↓ ↓H␈↓␈↓ αH␈↓ β_␈↓αf[(A B);3]␈↓ ∧8␈↓ ¬x␈↓ εHprog[[l;x]...]␈↓ πh␈↓ λ8␈↓ λ[l ← 2; l u ← g[y;x;z];...]
␈↓ ↓H␈↓α␈↓ αH␈↓ β_␈↓E␈↓β0␈↓␈↓ ∧8␈↓ ¬x␈↓ εHE␈↓β1␈↓␈↓ πh␈↓ λ8␈↓ λE␈↓β2␈↓
␈↓ ↓H␈↓␈↓ αH /␈↓ β_| /␈↓ ∧8␈↓ ¬x E␈↓β0␈↓␈↓ εH| E␈↓β0␈↓␈↓ πh␈↓ λ8 E␈↓β1␈↓␈↓ λ| E␈↓β1␈↓
␈↓ ↓H␈↓␈↓ αH_______␈↓ ∧8=>␈↓ ¬x_______␈↓ πh=>␈↓ λ8_______ =>
␈↓ ↓H␈↓␈↓ αH␈↓α f␈↓ β_| λ[[y;z] prog[...]]␈↓ ¬x y␈↓ εH| (A B)␈↓ πh␈↓ λ8 l␈↓ λ| ( )
␈↓ ↓H␈↓α␈↓ αH g␈↓ β_| λ[[x;y;z] prog[...]]␈↓ ¬x z␈↓ εH| 3␈↓ πh␈↓ λ8 x␈↓ λ| ( )
␈↓ ↓H␈↓At␈α∂this␈α∂point␈α∂we␈α∂have␈α∂done␈α∂the␈α∂λ-binding␈α∂and␈α∂initialized␈α∂the␈α∂␈↓αprog␈↓ variables.␈α∂ As␈α∂we␈α⊂begin␈α∂the
␈↓ ↓H␈↓execution␈αof␈αthe␈α
␈↓αprog␈↓ body,␈αwe␈αassign␈α
␈↓α2␈↓␈αto␈α␈↓αl␈↓␈α
and,␈αsince␈αlabels␈α
have␈αno␈αcomputational␈α
effect,␈αbegin
␈↓ ↓H␈↓the evaluation of the assignment statement: ␈↓αu ← g[y;x;z]␈↓:
␈↓ ↓H␈↓␈↓ β(␈↓ ∧(␈↓α[... l u ← g[y;x;z];...]␈↓ ε_␈↓ εh␈↓ π_[...u ← g[y;x;z]; ...]
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧(E␈↓β2␈↓α␈↓ ε_␈↓ εh␈↓ π_E␈↓β2␈↓α
␈↓ ↓H␈↓α␈↓ β( E␈↓β1␈↓α␈↓ ∧(| E␈↓β1␈↓α␈↓ ε_␈↓ εh E␈↓β1␈↓α␈↓ π_| E␈↓β1␈↓α
␈↓ ↓H␈↓α␈↓ β( __________␈↓ ε_=>␈↓ εh_________
␈↓ ↓H␈↓α␈↓ β( l␈↓ ∧(| 2␈↓ ε_␈↓ εhl␈↓ π_| 2
␈↓ ↓H␈↓α␈↓ β( x␈↓ ∧(| ( )␈↓ ε_␈↓ εhx␈↓ π_| ( )
␈↓ ↓H␈↓␈↓↓176 Imperative Constructs in LISP␈↓ 24.2␈↓
␈↓ ↓H␈↓We evaluate ␈↓αg[y;x;z]␈↓:
␈↓ ↓H␈↓␈↓ β(␈↓ ∧(␈↓αprog[[ ] ...]␈↓ ε_␈↓ εh[...go[l]; ... return[first[x]]; ...]
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧(E␈↓β3␈↓α␈↓ ε_␈↓ εh␈↓ π_E␈↓β4␈↓α
␈↓ ↓H␈↓α␈↓ β( E␈↓β2␈↓α␈↓ ∧(| E␈↓β2␈↓α␈↓ ε_␈↓ εh E␈↓β3␈↓α␈↓ π_| E␈↓β3␈↓α
␈↓ ↓H␈↓α␈↓ β( __________␈↓ ε_=>␈↓ εh_________
␈↓ ↓H␈↓α␈↓ β( x␈↓ ∧(| (A B)
␈↓ ↓H␈↓α␈↓ β( y␈↓ ∧(| ( )
␈↓ ↓H␈↓α␈↓ β( z␈↓ ∧(| 3
␈↓ ↓H␈↓The␈α∞␈↓αgo[l]␈↓␈α∂will␈α∞search␈α∂the␈α∞control␈α∂chain;␈α∞it␈α∂looks␈α∞in␈α∞the␈α∂␈↓αprog␈↓␈α∞form␈α∂of␈α∞E␈↓β3␈↓␈α∂but␈α∞finds␈α∂no␈α∞label␈α∂␈↓αl␈↓.␈α∞It
␈↓ ↓H␈↓examines␈α∩the␈α∩␈↓αprog␈↓␈α⊃of␈α∩E␈↓β1␈↓␈α∩next,␈α⊃and␈α∩there␈α∩it␈α∩does␈α⊃find␈α∩the␈α∩label␈α⊃␈↓αl␈↓.␈α∩Thus␈α∩execution␈α∩would␈α⊃be
␈↓ ↓H␈↓continued␈αat␈αthe␈αassignment␈αstatement␈αusing␈αE␈↓β2␈↓,␈αthe␈αenvironment␈αwhich␈αbound␈αthe␈α␈↓αprog␈↓ variables.
␈↓ ↓H␈↓In general, we continue in the environment which was created on entry to the ␈↓αprog␈↓ body.
␈↓ ↓H␈↓Notice␈αthat␈αonce␈αwe␈αhave␈αleft␈αE␈↓β4␈↓␈αthere␈αis␈αno␈αway␈αto␈αjump␈αback␈αinto␈αit.␈α We␈αcan␈αonly␈αsearch␈αdown
␈↓ ↓H␈↓the␈α∞control␈α∞chain,␈α∞and␈α
the␈α∞entry␈α∞to␈α∞␈↓αg␈↓␈α
is␈α∞not␈α∞below␈α∞that␈α
of␈α∞␈↓αf␈↓␈α∞on␈α∞that␈α
chain.␈α∞ An␈α∞extension␈α∞of␈α
the
␈↓ ↓H␈↓semantics␈αof␈αLISP␈αcould␈αallow␈αsuch␈αgeneralized␈αcontrol␈αand␈αwe␈αwill␈αdevelop␈αsome␈αof␈αthose␈αideas␈αin
␈↓ ↓H␈↓Section 4.4.
␈↓ ↓H␈↓If␈αwe␈αexecuted␈αthe␈α␈↓αreturn[first[x]]␈↓␈αin␈αE␈↓β4␈↓␈αan␈αaction␈αsimilar␈αto␈αthat␈αof␈α␈↓αgo␈↓␈αwould␈αtranspire.␈αWe␈αwould
␈↓ ↓H␈↓evaluate␈α␈↓αfirst[x]␈↓,␈αgetting␈α␈↓αA␈↓.␈αWe␈αwould␈αsearch␈αthe␈αcontrol␈αchain␈αfor␈αthe␈α␈↓↓latest␈↓␈α␈↓αprog␈↓ expression;␈αhere
␈↓ ↓H␈↓found␈αin␈αE␈↓β3␈↓;␈αand␈αthen␈αreturn␈αcontrol␈α
to␈αthe␈αenvironment␈αdesignated␈αin␈αthe␈αcontrol␈α
quadrant;␈αhere
␈↓ ↓H␈↓E␈↓β2␈↓.␈α⊃Thus␈α⊃we␈α⊃return␈α⊃␈↓αA␈↓␈α⊃as␈α⊃the␈α⊃value␈α⊃of␈α∩␈↓αg[y;x;z]␈↓.␈α⊃Since␈α⊃the␈α⊃call␈α⊃on␈α⊃␈↓αg␈↓␈α⊃was␈α⊃a␈α⊃component␈α∩of␈α⊃the
␈↓ ↓H␈↓assignment␈α␈↓αu ← g[y;x;z]␈↓,␈α
we␈αmust␈αcomplete␈α
that␈αassignment.␈αWe␈α
search␈αthe␈α␈↓↓access␈↓␈α
chain␈αfor␈α␈↓αu␈↓.␈α
Since
␈↓ ↓H␈↓␈↓αu␈↓ is not found we make a global assignment in E␈↓β0␈↓:
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬HE␈↓β0␈↓
␈↓ ↓H␈↓␈↓ ∧H␈↓ ¬H/| /␈↓β
␈↓ ↓H␈↓β␈↓ ∧H______________␈↓α
␈↓ ↓H␈↓α␈↓ ∧H f␈↓ ¬H| λ[[y;z] ...]
␈↓ ↓H␈↓α␈↓ ∧H g␈↓ ¬H| λ[[x;y;z] ...]
␈↓ ↓H␈↓α␈↓ ∧H u␈↓ ¬H| A
␈↓ ↓H␈↓The␈αability␈αto␈αevaluate␈αthe␈αargument␈αto␈α␈↓αgo␈↓␈αresults␈αin␈αa␈αuseful␈αprogramming␈αtrick.␈α Let␈α␈↓αl␈↓␈αbe␈αa␈αlist␈αof
␈↓ ↓H␈↓dotted␈α
pairs,␈α
each␈αof␈α
the␈α
form,␈α␈↓α(␈↓object␈↓βi␈↓␈α
.␈α
label␈↓βi␈↓α)␈↓.␈αAt␈α
each␈α
label␈↓βi␈↓␈αwe␈α
begin␈α
a␈αpiece␈α
of␈α
program␈α
to␈αbe
␈↓ ↓H␈↓executed when object␈↓βi␈↓ has been recognized. Then the construct:
␈↓ ↓H␈↓␈↓ UGH␈↓␈↓ ¬a␈↓αgo[cdr[assoc[x;l]]]␈↓
␈↓ ↓H␈↓can␈αbe␈αused␈αto␈α"dispatch"␈αto␈αthe␈αappropriate␈αcode␈αwhen␈α␈↓αx␈↓␈αis␈αone␈αof␈αthe␈αobject␈↓βi␈↓.␈αThis␈αis␈αan␈αinstance
␈↓ ↓H␈↓of␈α␈↓↓table-driven␈↓␈αprogramming.␈α The␈αblocks␈αof␈αcode␈αdispatched␈αto␈αcan␈αbe␈αdistributed␈αthroughout␈αthe
␈↓ ↓H␈↓body␈αof␈αthe␈α
␈↓αprog␈↓.␈αEach␈αblock␈α
of␈αcode␈αwill␈α
usually␈αbe␈αfollowed␈α
by␈αa␈α␈↓αgo␈↓␈α
back␈αto␈αthe␈α
code␈αinvolving
␈↓ ↓H␈↓␈↓↓4.2␈↓ →The ␈↓αprog␈↓↓-feature 177␈↓α
␈↓ ↓H␈↓equation␈α
␈↓ UGH␈↓␈α
(above).␈αIn␈α
fact␈α
the␈αargument␈α
␈↓αl␈↓␈α
in␈α
␈↓ UGH␈↓␈αmay␈α
be␈α
␈↓↓global␈↓␈αto␈α
the␈α
␈↓αprog␈↓-body.␈α The␈α
effect
␈↓ ↓H␈↓is␈α
to␈α∞make␈α
a␈α
␈↓αprog␈↓␈α∞which␈α
is␈α∞very␈α
difficult␈α
to␈α∞understand.␈α
The␈α
LISP␈α∞␈↓αselect␈↓␈α
(page 143)␈α∞will␈α
handle
␈↓ ↓H␈↓many␈αof␈αthe␈αpossible␈αapplications␈αof␈αthis␈αcoding␈αtrick␈αand␈αresult␈αin␈αa␈αmore␈αreadable␈αprogram.␈αThe
␈↓ ↓H␈↓case-statement␈α
(page 179)␈α
present␈α
in␈α
some␈α
other␈α
languages␈α
is␈α
also␈α
a␈α
better␈α
means␈α
of␈α∞handling␈α
this
␈↓ ↓H␈↓problem.
␈↓ ↓H␈↓The␈α∂␈↓αgo␈↓␈α∂statement␈α∂is␈α∂useful␈α⊂if␈α∂used␈α∂with␈α∂discretion.␈α∂It␈α⊂is␈α∂a␈α∂building␈α∂block␈α∂for␈α⊂constructing␈α∂more
␈↓ ↓H␈↓complex␈αcontrol␈αregimes,␈αparticularly␈αsince␈αthe␈αlabel␈αneed␈αnot␈αbe␈αlocal␈αto␈αthe␈α␈↓αprog␈↓␈αbut␈αonly␈αneed␈αbe
␈↓ ↓H␈↓accessible␈α∪through␈α∪the␈α∀control␈α∪chain.␈α∪We␈α∀will␈α∪examine␈α∪some␈α∀more␈α∪complex␈α∪kinds␈α∀of␈α∪control
␈↓ ↓H␈↓behavior in Section 4.4.
␈↓ ↓H␈↓Now to the problem of translating a ␈↓αprog␈↓ into an S-expression representation: the construct,
␈↓ ↓H␈↓␈↓ ∧I␈↓αprog[[v␈↓β1␈↓α; ...; v␈↓βn␈↓α] ... ]␈↓ will be translated to:
␈↓ ↓H␈↓␈↓ ¬;␈↓α(PROG(V1 ... VN) ... )␈↓.
␈↓ ↓H␈↓The␈α
body␈α
of␈α
the␈α
␈↓αprog␈↓␈α
must␈α
be␈α
handled␈α
specially␈α∞by␈α
a␈α
new␈α
piece␈α
of␈α
the␈α
evaluator␈α
since␈α
␈↓αprog␈↓␈α∞is␈α
a
␈↓ ↓H␈↓special form.
␈↓ ↓H␈↓We␈α
must␈α
also␈α
be␈α
careful␈α
about␈α
the␈α
interpretation␈α
of␈α
←.␈α
We␈α
will␈α
write␈α
␈↓αx␈α
←␈α
y␈↓␈α
in␈α
prefix␈αform:␈α
␈↓αsetq[x;y]␈↓.
␈↓ ↓H␈↓We will map this to:
␈↓ ↓H␈↓␈↓ ¬{␈↓α(SETQ X Y).␈↓
␈↓ ↓H␈↓The␈αassignment,␈α
␈↓αsetq␈↓,␈αis␈α
also␈αa␈α
special␈αform.␈α
For␈αif␈α␈↓αx␈↓␈α
and␈α␈↓αy␈↓␈α
have␈αvalues␈α
␈↓α2␈↓␈αand␈α
␈↓α3␈↓,␈αfor␈αexample,␈α
then
␈↓ ↓H␈↓the␈α∞call-by-value␈α∞interpretation␈α∞of␈α∂␈↓αsetq[x;y]␈↓␈α∞would␈α∞say␈α∞␈↓αsetq[2;3]␈↓.␈α∂This␈α∞was␈α∞not␈α∞our␈α∂intention.␈α∞ We
␈↓ ↓H␈↓want to evaluate the second argument to ␈↓αsetq␈↓ while stopping the evaluation of the first argument.
␈↓ ↓H␈↓LISP␈αhas␈αanother␈αassignment-like␈αoperator␈αcalled␈α␈↓αset␈↓.␈α Both␈αarguments␈αof␈αthis␈αbinary␈αoperator␈αare
␈↓ ↓H␈↓evaluated;␈αthe␈αvalue␈αof␈αthe␈αfirst␈αargument␈αis␈αexpected␈αto␈αbe␈αa␈αrepresentation␈αof␈αa␈αvariable;␈αthat␈αis,
␈↓ ↓H␈↓the␈αfirst␈αargument␈αevaluates␈αto␈αa␈αliteral␈αatom.␈α The␈αsecond␈αargument␈αis␈αa␈αLISP␈αform␈αand␈αusing␈αthe
␈↓ ↓H␈↓value␈αof␈αthat␈αform,␈αan␈αassignment␈αis␈αmade␈αto␈αthe␈αvariable␈αrepresented␈αby␈αthe␈αfirst␈αargument.␈αThus
␈↓ ↓H␈↓␈↓αsetq[x;y]␈↓ is synonymous with ␈↓αset[quote[x];y]␈↓.
␈↓ ↓H␈↓As␈α∂a␈α∞more␈α∂complex␈α∞example,␈α∂consider␈α∞␈↓αset[z;␈α∂plus[x;1]]␈↓.␈α∞ If␈α∂the␈α∞current␈α∂value␈α∞of␈α∂variable␈α∞␈↓αz␈↓␈α∂is␈α∞an
␈↓ ↓H␈↓identifier,␈αthen␈α
␈↓αset[z;␈αplus[x;1]]␈↓␈α
makes␈αsense.␈α
Assume␈αthe␈αcurrent␈α
value␈αof␈α
␈↓αz␈↓␈αis␈α
␈↓αA␈↓;␈αand␈α
assume␈αthe
␈↓ ↓H␈↓current␈α
value␈αof␈α
␈↓αx␈↓␈αis␈α
␈↓α2␈↓;␈αsince␈α
␈↓αA␈↓␈αrepresents␈α
the␈α
identifier␈α␈↓αa␈↓,␈α
the␈αeffect␈α
of␈αthe␈α
␈↓αset␈↓␈αstatement␈α
is␈αto␈α
assign
␈↓ ↓H␈↓the␈α∞value␈α∞␈↓α3␈↓␈α∞to␈α∞␈↓αa␈↓.␈α∂ Normally␈α∞when␈α∞making␈α∞assignments,␈α∞we␈α∞want␈α∂to␈α∞assign␈α∞to␈α∞a␈α∞␈↓↓name␈↓␈α∞and␈α∂not␈α∞a
␈↓ ↓H␈↓␈↓↓value␈↓; thus we will tend to use the ␈↓αsetq␈↓ form.
␈↓ ↓H␈↓␈↓↓178 Imperative Constructs in LISP␈↓ 24.2␈↓
␈↓ ↓H␈↓Finally, here is a translation of the body of the ␈↓αprog␈↓ version of ␈↓αlength:␈↓ ␈↓α
␈↓ ↓H␈↓α␈↓ α((LAMBDA␈↓ βH(L)
␈↓ ↓H␈↓α␈↓ α(␈↓ βH(PROG (L1 C)
␈↓ ↓H␈↓α␈↓ α(␈↓ βH␈↓ βx(SETQ L1 L)
␈↓ ↓H␈↓α␈↓ α(␈↓ βH␈↓ βx(SETQ C 0)
␈↓ ↓H␈↓α␈↓ α(␈↓ βHA␈↓ βx(COND ((NULL L1) (RETURN C)))
␈↓ ↓H␈↓α␈↓ α(␈↓ βH␈↓ βx(SETQ C (ADD1 C))
␈↓ ↓H␈↓α␈↓ α(␈↓ βH␈↓ βx(SETQ L1 (REST L1))
␈↓ ↓H␈↓α␈↓ α(␈↓ βH␈↓ βx(GO A) ))
␈↓ ↓H␈↓α␈↓Now␈α⊃that␈α⊃assignment␈α∩statements␈α⊃have␈α⊃been␈α⊃described,␈α∩let's␈α⊃re-examine␈α⊃"<=".␈α⊃We␈α∩already␈α⊃know
␈↓ ↓H␈↓(page 133)␈αthat␈α"<="␈αdoes␈αmore␈αthan␈αsimply␈αassociate␈αthe␈αright␈αhand␈αside␈αwith␈αa␈αsymbol␈αtable␈αentry
␈↓ ↓H␈↓of␈α⊃the␈α⊂left␈α⊃hand␈α⊂side;␈α⊃it␈α⊂must␈α⊃also␈α⊂associate␈α⊃an␈α⊂environment␈α⊃with␈α⊂the␈α⊃function␈α⊂body,␈α⊃and␈α⊂this
␈↓ ↓H␈↓environment␈α⊗is␈α⊗to␈α⊗be␈α⊗used␈α⊗for␈α∃accessing␈α⊗non-local␈α⊗variables.␈α⊗This␈α⊗operation␈α⊗of␈α∃associating
␈↓ ↓H␈↓environments is called forming the ␈↓↓closure␈↓. We thus might be tempted to say:
␈↓ ↓H␈↓α␈↓ ∧Af <= λ[[ ... ] ...] ␈↓is␈↓α f ← function[λ[[ ...] ...] ].
␈↓ ↓H␈↓Alas, this implementation is still not sufficient as we will see in Section 4.11.
␈↓ ↓H␈↓␈↓ ¬+␈↓↓Problems involving ␈↓αprog␈↓↓␈↓α
␈↓ ↓H␈↓I. Write ␈↓αprog␈↓-versions of the following functions (or predicates).
␈↓ ↓H␈↓␈↓↓1.␈↓α␈α
member␈α<=␈α
λ[[x;y]␈α...]␈↓:␈↓α␈α
x␈↓␈αis␈α
atomic;␈α␈↓αy␈↓␈α
is␈αa␈α
list␈α
of␈αatoms.␈α
␈↓αmember␈↓␈αis␈α
to␈αreturn␈α
␈↓
t␈↓␈αjust␈α
in␈αthe␈α
case␈αthat␈α
␈↓αx␈↓
␈↓ ↓H␈↓␈↓ βXis one of the elements in ␈↓αy␈↓.
␈↓ ↓H␈↓␈↓↓2.␈↓ The factorial function.
␈↓ ↓H␈↓␈↓↓3.␈↓α␈αdelete␈α<=␈αλ[[x;y]␈α...␈α]␈↓:␈α␈↓αx␈↓␈αis␈αatomic;␈α␈↓αy␈↓␈αis␈αa␈αlist␈αof␈αatoms.␈α ␈↓αdelete␈↓␈αis␈αto␈αreturn␈αa␈αlist␈αwhich␈αlooks␈αlike␈α␈↓αy␈↓,
␈↓ ↓H␈↓␈↓ β8except all occurrences of ␈↓αx␈↓ have been deleted.
␈↓ ↓H␈↓␈↓↓4.␈↓ The ␈↓αappend␈↓ function.
␈↓ ↓H␈↓␈↓↓5.␈↓α last <= λ[[x] ...]␈↓: ␈↓αx␈↓ is a non-empty list. ␈↓αlast␈↓ is to return the last element in ␈↓αx␈↓.
␈↓ ↓H␈↓␈↓↓6.␈↓ Now write the S-expr translations of each of your functions.
␈↓ ↓H␈↓II. What is necessary to extend the evaluator to recognize ␈↓αprog␈↓ and friends?
␈↓ ↓H␈↓␈↓↓4.2␈↓ →The ␈↓αprog␈↓↓-feature 179␈↓α
␈↓ ↓H␈↓III.␈αThe␈α␈↓αgo[cdr[...]]␈↓-construct␈αon␈αpage 176␈αis␈αbetter␈αhandled␈αwith␈αa␈α␈↓↓case␈αstatement␈↓.␈αA␈αtypical␈αsyntax
␈↓ ↓H␈↓␈↓ αλfor such might be:
␈↓ ↓H␈↓␈↓ ∧jcase<index>of <form␈↓β1␈↓>; ... ;<form␈↓βn␈↓>.
␈↓ ↓H␈↓<index>␈α⊃is␈α⊃to␈α⊂evaluate␈α⊃to␈α⊃an␈α⊂integer,␈α⊃i.␈α⊃Where␈α⊂0<i≤n.␈α⊃The␈α⊃i␈↓πth␈↓␈α⊂<form>␈α⊃of␈α⊃the␈α⊃case-statement␈α⊂is
␈↓ ↓H␈↓␈↓ αλexecuted,␈αand␈αis␈αthe␈αvalue␈αof␈αthe␈αstatement.␈α Give␈αa␈αrepresentation␈αfor␈αthe␈αcase␈αstatement␈αand
␈↓ ↓H␈↓␈↓ αλextend the evaluator to recognize it.
␈↓ ↓H␈↓IV. Some languages allow constructs like:
␈↓ ↓H␈↓␈↓ βP(␈↓↓if␈↓ p(x) ␈↓↓then␈↓ x ␈↓↓else␈↓ y) ← exp, which is to mean the same as:
␈↓ ↓H␈↓␈↓ ∧|␈↓↓if␈↓ p(x) ␈↓↓then␈↓ x← exp ␈↓↓else␈↓ y ← exp
␈↓ ↓H␈↓Can such a construct be written in LISP?
␈↓ ↓H␈↓V.␈α⊂Compare␈α∂the␈α⊂␈↓αprog␈↓␈α∂version␈α⊂of␈α∂␈↓αlength␈↓␈α⊂on␈α⊂page 172␈α∂with␈α⊂␈↓αlength␈↓β1␈↓␈α∂on␈α⊂page 45.␈α∂Do␈α⊂you␈α⊂see␈α∂any
␈↓ ↓H␈↓␈↓ αλinteresting relationships?
␈↓ ↓H␈↓VI.␈α+Give␈α+a␈α+macro␈α+definition␈α+of␈α+an␈α+extended␈α+␈↓αSETQ␈↓,␈α+which␈α+is␈α+called␈α+as
␈↓ ↓H␈↓␈↓ αλ␈↓α(SETQ ␈↓var␈↓β1␈↓ exp␈↓β1␈↓ ... var␈↓βn␈↓ exp␈↓βn␈↓α)␈↓.␈α∀ Each␈α∀var␈↓βi␈↓␈α∀is␈α∀a␈α∃name;␈α∀each␈α∀exp␈↓βi␈↓␈α∀is␈α∀an␈α∀expression␈α∃to␈α∀be
␈↓ ↓H␈↓␈↓ αλevaluated␈α∃and␈α⊗assigned␈α∃to␈α∃var␈↓βi␈↓.␈α⊗The␈α∃assignments␈α∃should␈α⊗go␈α∃from␈α⊗"left-to-right".␈α∃ Thus
␈↓ ↓H␈↓␈↓ αλ␈↓α(SETQ X 2 Y (TIMES 2 X) X 3)␈↓ when executed should assign ␈↓α3␈↓ to ␈↓αX␈↓ and ␈↓α4␈↓ to ␈↓αY␈↓.
␈↓ ↓H␈↓VII. Express ␈↓αsetq␈↓ as a macro over ␈↓αset␈↓.
␈↓ ↓H␈↓VIII.␈α
Write␈αa␈α
␈↓αprog␈↓␈αwhich␈α
will␈αterminate␈α
if␈αcall-by-value␈α
evaluation␈αis␈α
used,␈αbut␈α
will␈α
not␈αterminate
␈↓ ↓H␈↓␈↓ αλunder call-by-name.
␈↓ ↓H␈↓IX.␈α∞ Use␈α∞your␈α∞␈↓αprog␈↓␈α
version␈α∞of␈α∞␈↓αfact␈↓␈α∞(prob I, ␈↓↓2␈↓)␈α
and␈α∞evaluate␈α∞␈↓αfact[2]␈↓␈α∞using␈α∞Weizenbaum␈α
diagrams.
␈↓ ↓H␈↓␈↓ αλNote␈α
the␈α∞difference␈α
between␈α
the␈α∞internal␈α
structures␈α
used␈α∞here␈α
and␈α
the␈α∞structures␈α
used␈α∞in␈α
the
␈↓ ↓H␈↓␈↓ αλrecursive␈αversion.␈αThis␈αdifference␈αin␈αimplementation␈αoverhead␈αis␈αa␈αquantitive␈αmeasure␈αof␈αthe
␈↓ ↓H␈↓␈↓ αλexpense of recursion versus the expense of iteration.
␈↓ ↓H␈↓␈↓ ¬.␈↓↓4.3 Alternatives to ␈↓αprog␈↓␈↓α
␈↓ ↓H␈↓The␈α⊃␈↓αprog␈↓␈α⊂feature␈α⊃of␈α⊂LISP␈α⊃is␈α⊃an␈α⊂effective␈α⊃means␈α⊂for␈α⊃encoding␈α⊂iterative␈α⊃algorithms,␈α⊃however␈α⊂it
␈↓ ↓H␈↓suffers␈α⊂from␈α⊂a␈α⊂few␈α⊂draw-backs.␈α⊂For␈α⊂example,␈α⊂The␈α⊂label-and-␈↓αgo␈↓␈α⊂style␈α⊂of␈α⊂control␈α⊂is␈α⊂only␈α⊃a␈α⊂slight
␈↓ ↓H␈↓elaboration␈αof␈α
the␈αcontrol␈α
mechanisms␈αwhich␈αare␈α
typically␈αused␈α
to␈αcontrol␈α
a␈αhardware␈αmachine,␈α
and
␈↓ ↓H␈↓thus␈α∞the␈α
level␈α∞of␈α
description␈α∞which␈α
is␈α∞required␈α∞tends␈α
to␈α∞obscure␈α
the␈α∞actual␈α
flow␈α∞of␈α∞the␈α
algorithm
␈↓ ↓H␈↓unless␈α⊂the␈α∂programmer␈α⊂is␈α∂careful.␈α⊂A␈α∂slight␈α⊂extension␈α∂to␈α⊂conditional␈α∂expressions␈α⊂and␈α∂conditional
␈↓ ↓H␈↓statements can alleviate some of the confusion which is likely when constucting complex ␈↓αprog␈↓s.
␈↓ ↓H␈↓␈↓↓180 Imperative Constructs in LISP␈↓ 24.3␈↓
␈↓ ↓H␈↓Conditional␈αexpressions␈αare␈αcurrently␈αdefined␈αsuch␈αthat␈αeach␈αe␈↓βi␈↓␈αmust␈αbe␈αa␈αsingle␈αexpression.␈α With
␈↓ ↓H␈↓the␈αintroduction␈αof␈αside␈αeffects,␈α
it␈αis␈αconvenient␈αto␈αextend␈α
conditionals␈αto␈αinclude␈αcomponents␈αof␈α
the
␈↓ ↓H␈↓form:␈α∂p␈↓βi␈↓ → e␈↓βi1␈↓; ... ;e␈↓βin␈↓.␈α⊂ This␈α∂extended␈α⊂component␈α∂is␈α∂to␈α⊂be␈α∂evaluated␈α⊂as␈α∂follows:␈α∂if␈α⊂p␈↓βi␈↓␈α∂is␈α⊂true,␈α∂then
␈↓ ↓H␈↓evaluate the e␈↓βij␈↓'s from left to right, with the value of the component to be the value of e␈↓βin␈↓␈↓π 129␈↓.
␈↓ ↓H␈↓For example, this feature, used in ␈↓αprog␈↓s would allow us to replace:
␈↓ ↓H␈↓␈↓ αX␈↓ β_ ....
␈↓ ↓H␈↓␈↓ αX␈↓ β_[p␈↓β1␈↓ → ␈↓αgo[l]]
␈↓ ↓H␈↓α␈↓ αXm
␈↓ ↓H␈↓α␈↓ αX␈↓ β_ ...
␈↓ ↓H␈↓α␈↓ αX␈↓ β_return[␈↓
t␈↓α];
␈↓ ↓H␈↓α␈↓ αXl␈↓ β_␈↓e␈↓β1␈↓;
␈↓ ↓H␈↓␈↓ αX␈↓ β_e␈↓β2␈↓;
␈↓ ↓H␈↓␈↓ αX␈↓ β_ ...
␈↓ ↓H␈↓␈↓ αX␈↓ β_␈↓αgo[m];
␈↓ ↓H␈↓with:
␈↓ ↓H␈↓␈↓ ∧} ... [p␈↓β1␈↓ → e␈↓β1␈↓;e␈↓β2␈↓; ... ] ...; ␈↓αreturn[␈↓
t␈↓α]].
␈↓ ↓H␈↓The␈α∞improved␈α∞readibility␈α∞is␈α∞largely␈α∞do␈α∞to␈α∂the␈α∞localizing␈α∞or␈α∞"packaging"␈α∞of␈α∞the␈α∞actions␈α∂with␈α∞their
␈↓ ↓H␈↓initiators;␈αwe␈αneed␈αnot␈αscan␈αan␈αarbitrarily␈αlong␈αpiece␈αof␈αtext␈αto␈αdiscover␈αwhat␈αthe␈αcomputation␈αwill
␈↓ ↓H␈↓be when the predicate is true.
␈↓ ↓H␈↓Several␈α
languages␈α
have␈αincluded␈α
more␈α
"packaged"␈αversions␈α
of␈α
iterative␈αcontrol.␈α
The␈α
motivation␈αis
␈↓ ↓H␈↓similar␈α∂to␈α∂that␈α∂which␈α∂we␈α∂used␈α∂in␈α∂justifying␈α∂recursive␈α∂control:␈α∂we␈α∂didn't␈α∂care␈α∂␈↓↓how␈↓␈α∂recursion␈α∞was
␈↓ ↓H␈↓implemented, all we wished to discuss was the ␈↓↓effect␈↓ or ␈↓↓behavior␈↓ of recursion␈↓π 130␈↓.
␈↓ ↓H␈↓An␈α
iterative␈α
unit␈α
must␈α∞allow␈α
the␈α
programmer␈α
a␈α
reasonable␈α∞degree␈α
of␈α
freedom␈α
and␈α∞naturalness␈α
in
␈↓ ↓H␈↓expression.␈α⊃What␈α⊃should␈α⊂also␈α⊃be␈α⊃recognized␈α⊃is␈α⊂that␈α⊃the␈α⊃structural␈α⊂unit␈α⊃should␈α⊃be␈α⊃amenable␈α⊂to
␈↓ ↓H␈↓analysis␈α
to␈αthe␈α
same␈αdegree␈α
as␈αthat␈α
allowed␈αin␈α
recursion.␈αWe␈α
must␈αbe␈α
able␈αto␈α
state␈αprecise␈α
properties
␈↓ ↓H␈↓of␈α⊃algorithms␈α⊃which␈α⊃use␈α∩these␈α⊃constructs,␈α⊃and␈α⊃we␈α⊃should␈α∩be␈α⊃able␈α⊃to␈α⊃prove␈α⊃properties␈α∩of␈α⊃such
␈↓ ↓H␈↓algorithms.␈α With␈αthe␈αcontrol␈αof␈αthe␈αloop␈αstructure␈αin␈αthe␈αlanguage␈αrather␈αthan␈αin␈αthe␈αhands␈αof␈αthe
␈↓ ↓H␈↓programmer,␈α⊃the␈α⊃static␈α∩text␈α⊃and␈α⊃the␈α∩dynamic␈α⊃flow␈α⊃of␈α⊃the␈α∩execution␈α⊃have␈α⊃a␈α∩close␈α⊃relationship.
␈↓ ↓H␈↓General␈α∂use␈α∂of␈α∂label-and-␈↓αgo␈↓'s␈α∂and␈α∂assignments␈α∞does␈α∂not␈α∂maintain␈α∂such␈α∂properties.␈α∂ Our␈α∞iterative
␈↓ ↓H␈↓control␈α∞construct␈α∂should␈α∞therefore␈α∂capture␈α∞all␈α∂of␈α∞the␈α∞essential␈α∂ingredients␈α∞of␈α∂an␈α∞iteration,␈α∂and␈α∞its
␈↓ ↓H␈↓semantics should be restricted such that its static text does indeed reflect its dynamic flow.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 129␈↓␈α
This␈α
extended␈α∞conditional␈α
expression␈α
([Bob 69])␈α∞is␈α
available␈α
on␈α
versions␈α∞of␈α
LISP␈α
1.6␈α∞on␈α
the
␈↓ ↓H␈↓PDP-10 [Moo 74], [Qua 72], [Int 75].
␈↓ ↓H␈↓␈↓π 130␈↓␈α
We␈α
␈↓↓could␈↓␈α
have␈α
replaced␈α
recursive␈α
control␈α
with␈α
an␈α
appropriate␈α
combination␈α
of␈α
label-and-␈↓αgo␈↓'s.
␈↓ ↓H␈↓and a simulated stack. We will do so shortly.
␈↓ ↓H␈↓␈↓↓4.3␈↓ λpAlternatives to ␈↓αprog␈↓ 181␈↓α
␈↓ ↓H␈↓Our␈αfirst␈α
example␈αis␈αbased␈α
on␈αthe␈α
MacLISP␈α␈↓αdo␈↓␈α[Moo 74].␈α
With␈αsome␈α
inessential␈αchanges,␈αits␈α
syntax
␈↓ ↓H␈↓is:
␈↓ ↓H␈↓␈↓ ∧h␈↓αdo␈↓ ¬_[␈↓<var␈↓β1␈↓> <init␈↓β1␈↓> <step␈↓β1␈↓>;
␈↓ ↓H␈↓␈↓ ∧h␈↓ ¬_ <var␈↓β2␈↓> <init␈↓β2␈↓> <step␈↓β2␈↓>;
␈↓ ↓H␈↓␈↓ ∧h␈↓ ¬_ ...
␈↓ ↓H␈↓␈↓ ∧h␈↓ ¬_ <var␈↓βn␈↓> <init␈↓βn␈↓> <step␈↓βn␈↓>;
␈↓ ↓H␈↓␈↓ ∧h␈↓ ¬_[<pred> → <exit>]
␈↓ ↓H␈↓␈↓ ∧h␈↓ ¬_ <body> ]
␈↓ ↓H␈↓The␈αconstruct␈α
captures␈αthe␈α
ideas␈αof␈α
intialization␈αand␈αupdating␈α
of␈αvariables␈α
nicely.␈α Each␈α
<var␈↓βi␈↓>␈αis
␈↓ ↓H␈↓initialized␈αto␈αits␈α<init␈↓βi␈↓>-value␈αsimultaneously.␈α Each␈α<step␈↓βi␈↓>␈αis␈αa␈αform␈αwhich␈αwill␈αbe␈αevaluated␈αupon
␈↓ ↓H␈↓proper␈αcompletion␈αof␈αeach␈α
cycle␈αof␈αthe␈α␈↓αdo␈↓.␈αThe␈α
<pred>␈αis␈αevaluated,␈αand␈α
on␈αgiving␈αvalue␈α␈↓
t␈↓␈αthe␈α
loop
␈↓ ↓H␈↓will␈α∂terminate,␈α⊂returning␈α∂the␈α⊂value␈α∂of␈α∂<exit>.␈α⊂ If␈α∂<pred>␈α⊂gives␈α∂␈↓
f␈↓␈α∂then␈α⊂<body>␈α∂is␈α⊂executed.␈α∂This
␈↓ ↓H␈↓component␈α∞of␈α∂the␈α∞␈↓αdo␈↓␈α∞is␈α∂a␈α∞␈↓αprog␈↓␈α∞body;␈α∂when␈α∞the␈α∞last␈α∂statement␈α∞in␈α∞<body>␈α∂is␈α∞executed,␈α∂the␈α∞<step␈↓βi␈↓>
␈↓ ↓H␈↓forms are evaluated and assigned to the <var␈↓βi␈↓>'s, and another cycle of the ␈↓αdo␈↓ is begun.
␈↓ ↓H␈↓Since␈α
the␈α
<body>␈α
of␈α
the␈α
␈↓αdo␈↓␈α
is␈α
a␈α
␈↓αprog␈↓␈α
body,␈α
the␈α
␈↓αreturn␈↓␈α
statement␈α
may␈α
appear.␈α
This␈α
feature␈α
allows␈α
the
␈↓ ↓H␈↓dynamic flow to diverge from the static text␈↓π 131␈↓. But consider the ␈↓αdo␈↓ version of ␈↓αmember␈↓:
␈↓ ↓H␈↓α␈↓ αxmember <= λ[[a;l]␈↓ ∧hdo␈↓ ¬λ[x l rest[x];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧h␈↓ ¬λ [null[x] → ␈↓
f␈↓α]
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧h␈↓ ¬λ [eq[first[x];a] → return[␈↓
t␈↓α]] ]
␈↓ ↓H␈↓This␈α∩algorithm␈α∩could␈α∩be␈α∩expressed␈α∩without␈α∩␈↓αreturn␈↓␈α∩but␈α∩the␈α∩resulting␈α∩program␈α∩is␈α∩unnecessarily
␈↓ ↓H␈↓complex.
␈↓ ↓H␈↓An alternative iterative construct was proposed in [Wis 75].
␈↓ ↓H␈↓α␈↓ β+repeat[␈↓<st-list␈↓β1␈↓>;␈↓αwhile ␈↓<pred␈↓β1␈↓>; <st-list␈↓β2␈↓>; ␈↓αuntil ␈↓<pred␈↓β2␈↓>; <st-list␈↓β3␈↓>]
␈↓ ↓H␈↓where␈α
<pred␈↓βi␈↓>␈αis␈α
a␈αpredicate,␈α
and␈α<st-list␈↓βi␈↓>␈α
is␈αa␈α
list␈αof␈α
statements.␈αThe␈α
list␈αmay␈α
be␈αempty,␈α
but␈αmay
␈↓ ↓H␈↓not contain ␈↓αreturn␈↓s or ␈↓αgo␈↓s.
␈↓ ↓H␈↓The␈α
semantics␈αis␈α
as␈αfollows:␈α
<st-list␈↓β1␈↓>␈αis␈α
executed;␈α<pred␈↓β1␈↓>␈α
is␈αthen␈α
evaluated␈αand␈α
if␈αfalse␈α
we␈αexit␈α
the
␈↓ ↓H␈↓␈↓αrepeat␈↓␈αwith␈α␈↓
f␈↓.␈αIf␈α<pred␈↓β1␈↓>␈αis␈αtrue,␈αthen␈αwe␈αexecute␈α<st-list␈↓β2␈↓>␈αand␈αtest␈α<pred␈↓β2␈↓>;␈αif␈α<pred␈↓β2␈↓>␈αis␈αtrue␈αwe
␈↓ ↓H␈↓exit with ␈↓
t␈↓, otherwise we execute <st-list␈↓β3␈↓> and iterate the loop beginning again at <st-list␈↓β1␈↓>.
␈↓ ↓H␈↓For example we could write ␈↓αmember␈↓ as:
␈↓ ↓H␈↓α␈↓ αXmember <= λ[[a;l]
␈↓ ↓H␈↓α␈↓ αX␈↓ βxrepeat[while [not[null[l]]; until [equal[a;first[l]];l ← rest[l]]]
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 131␈↓␈αCompare␈αthis␈αto␈αthe␈αbehavior␈αof␈αfree␈αvariables␈αunder␈αdynamic␈αbinding.␈αFrom␈αa␈αprogramming
␈↓ ↓H␈↓point␈αof␈αview,␈αbeing␈αable␈αto␈αescape␈αfrom␈αthe␈αstatic␈αtext,␈αeither␈αfor␈αvariable␈αreference␈αor␈αfor␈αcontrol
␈↓ ↓H␈↓may be convenient. Whether either feature is "good practice" is a matter of taste.
␈↓ ↓H␈↓␈↓↓182 Imperative Constructs in LISP␈↓ 24.3␈↓
␈↓ ↓H␈↓The␈αdifficulty␈α
which␈αwe␈α
encountered␈αwith␈α
the␈αMacLISP␈α
␈↓αdo␈↓␈αhas␈α
been␈αalleviated,␈α
however␈αthe␈α
␈↓αrepeat␈↓
␈↓ ↓H␈↓construct␈α
has␈α
several␈α
shortcomings␈α
of␈α
its␈α
own.␈α
In␈α
particular,␈α
we␈α
have␈α
no␈α
means␈α
for␈α
designating␈α
what
␈↓ ↓H␈↓variables␈α
are␈α
to␈α
be␈αinitialized␈α
and␈α
incremented␈α
within␈α
the␈αloop.␈α
Such␈α
variables␈α
must␈α
be␈αdeclared
␈↓ ↓H␈↓and␈α
initialized␈α
external␈α
to␈α
the␈α
␈↓αrepeat␈↓;␈α
also␈α
the␈α
stepping␈α
of␈α
the␈α
loop␈α
variables␈α
must␈α
be␈α∞done␈α
using
␈↓ ↓H␈↓the␈α∞assignment␈α
statement.␈α∞ Similarly␈α
the␈α∞power␈α∞of␈α
expression␈α∞on␈α
leaving␈α∞the␈α
␈↓αrepeat␈↓␈α∞is␈α∞limited;␈α
we
␈↓ ↓H␈↓cannot␈α⊂explicitly␈α⊂declare␈α⊂what␈α⊂values␈α⊂are␈α⊂to␈α⊂be␈α⊂returned.␈α⊂The␈α⊂value␈α⊂is␈α⊂that␈α⊂of␈α⊂the␈α∂appropriate
␈↓ ↓H␈↓<pred␈↓βi␈↓>.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I.␈α
Some␈α
of␈α
the␈α
generality␈α
of␈α
␈↓αprog␈↓s␈α
can␈α
be␈αcontrolled␈α
by␈α
the␈α
use␈α
of␈α
a␈α
new␈α
control␈α
structure␈α
for␈αlist
␈↓ ↓H␈↓operations.␈α∞The␈α
construct␈α∞is␈α∞called␈α
␈↓αlit␈↓␈↓π 132␈↓.␈α∞ ␈↓αlit␈↓␈α∞takes␈α
three␈α∞arguments:␈α
a␈α∞binary␈α∞function␈α
␈↓αf␈↓,␈α∞a␈α∞list␈α
␈↓αl␈↓,
␈↓ ↓H␈↓and␈α
a␈α
value␈α
␈↓αv␈↓.␈α
If␈α
␈↓αl␈↓␈α
is␈α
empty,␈α
give␈α
␈↓αv␈↓;␈α∞otherwise␈α
apply␈α
␈↓αf␈↓␈α
to␈α
the␈α
first␈α
element␈α
of␈α
␈↓αl␈↓␈α
and␈α
the␈α∞effect␈α
of
␈↓ ↓H␈↓applying ␈↓αlit␈↓ to the remainder of ␈↓αl␈↓.
␈↓ ↓H␈↓For example ␈↓αappend␈↓ could be expressed as:
␈↓ ↓H␈↓α␈↓ ∧>append <= λ[[x;y] lit[function[concat];x;y]]
␈↓ ↓H␈↓Give a non-␈↓αprog␈↓ definition for ␈↓αlit␈↓.
␈↓ ↓H␈↓II.␈α
Here␈α
is␈α
another␈αuseful␈α
extension␈α
to␈α
LISP:␈αInstead␈α
of␈α
requiring␈α
that␈αthe␈α
body␈α
of␈α
a␈αλ-definition␈α
be
␈↓ ↓H␈↓a␈α
single␈α
expression:␈α
␈↓λx␈↓␈α
in␈α
␈↓αλ[[ ... ] ␈↓λx␈↓α]␈↓,␈α
allow␈αbodies␈α
of␈α
the␈α
form:␈α
␈↓λx␈↓β1␈↓α; ...; ␈↓λx␈↓βn␈↓α␈↓,␈α
giving␈α
rise␈α
to␈αλ-definitions
␈↓ ↓H␈↓like␈α∞␈↓αλ[[ ... ] ␈↓λx␈↓β1␈↓α; ...; ␈↓λx␈↓βn␈↓α]␈↓.␈α∞The␈α∞application␈α∞of␈α∞such␈α∞a␈α∞definition␈α∞means:␈α∞bind␈α∞the␈α∞λ-variables␈α∞as␈α∞usual,
␈↓ ↓H␈↓then evaluate the ␈↓λx␈↓βi␈↓'s from left to right returning as value, ␈↓λx␈↓βn␈↓.
␈↓ ↓H␈↓Extend the evaluator of Section 3.5 to handle such constructs.
␈↓ ↓H␈↓III. Give an S-expr representation for the ␈↓αrepeat␈↓ expression and add ␈↓αrepeat␈↓ to ␈↓αeval␈↓ of Section 3.5.
␈↓ ↓H␈↓␈↓ ¬8␈↓↓4.4 Extensions to ␈↓αeval␈↓␈↓α
␈↓ ↓H␈↓The␈αintroduction␈αof␈αthe␈α␈↓αprog␈↓-feature␈αcompletes␈αour␈αsyntactic␈αdescription␈αof␈αthe␈αlanguage␈αconstructs
␈↓ ↓H␈↓of␈αLISP.␈αWe␈αwould␈αlike␈αto␈αgive␈αa␈αnew␈αversion␈αof␈α␈↓αeval␈↓␈αwhich␈αdescribes␈αthe␈αsemantics␈αof␈α␈↓αprog␈↓s␈αin␈αa
␈↓ ↓H␈↓manner␈αwhich␈α
accurately␈αreflects␈α
the␈αtechniques␈α
used␈αin␈α
implementations.␈αWe␈α
could␈αsimply␈α
simulate
␈↓ ↓H␈↓␈↓αprog␈↓␈α∪behavior␈α∪using␈α∪recursive␈α∪techniques,␈α∪but␈α∪the␈α∪iterative␈α∪control␈α∪expressed␈α∪in␈α∪␈↓αprog␈↓s␈α∪is␈α∪an
␈↓ ↓H␈↓important␈α∞idea␈α∞in␈α∂its␈α∞own␈α∞right␈α∞and␈α∂is␈α∞a␈α∞simple␈α∞instance␈α∂of␈α∞non-recursive␈α∞control.␈α∂A␈α∞mechanism
␈↓ ↓H␈↓which␈α
faithfully␈αimplements␈α
such␈α
control␈αstructures␈α
leads␈αeasily␈α
to␈α
the␈αidea␈α
of␈α
␈↓↓generalized␈αcontrol
␈↓ ↓H␈↓↓structures␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 132␈↓ for ␈↓αl␈↓ist ␈↓αit␈↓erator [Bar 66]
␈↓ ↓H␈↓␈↓↓4.4␈↓ εExtensions to ␈↓αeval␈↓ 183␈↓α
␈↓ ↓H␈↓The␈α⊂second␈α⊂interesting␈α⊃feature␈α⊂introduced␈α⊂with␈α⊂␈↓αprog␈↓s␈α⊃was␈α⊂the␈α⊂assignment␈α⊂statement.␈α⊃Again,␈α⊂we
␈↓ ↓H␈↓could␈αmirror␈α
most␈αof␈α
the␈αbehavior␈α
of␈αassignments␈αby␈α
careful␈αuse␈α
of␈αthe␈α
techniques␈αof␈αrecursion␈α
and
␈↓ ↓H␈↓symbol␈α
tables,␈α
but␈αsuch␈α
modelling␈α
would␈α
not␈αadequately␈α
reflect␈α
the␈α
intent␈αof␈α
the␈α
construct␈α
or␈αgive
␈↓ ↓H␈↓insight␈α⊗into␈α∃the␈α⊗techniques␈α∃used␈α⊗in␈α⊗implementing␈α∃such␈α⊗constructs.␈α∃We␈α⊗could␈α⊗describe␈α∃such
␈↓ ↓H␈↓implementations␈α↔in␈α↔a␈α↔low-level␈α↔machine␈α⊗language,␈α↔but␈α↔such␈α↔practice␈α↔would␈α↔only␈α⊗introduce
␈↓ ↓H␈↓unnecessary␈α
details.␈α∞Rather,␈α
we␈α∞will␈α
describe␈α∞an␈α
evaluator␈α
in␈α∞LISP␈α
using␈α∞the␈α
techniques␈α∞we␈α
have
␈↓ ↓H␈↓been␈αdeveloping.␈α
In␈αthe␈αprocess␈α
we␈αwill␈αelucidate␈α
much␈αmore␈αthan␈α
just␈α␈↓αprog␈↓s␈αand␈α
assignments;␈αwe
␈↓ ↓H␈↓will␈α∂lay␈α∂bare␈α∂much␈α∂more␈α∞of␈α∂the␈α∂behavior␈α∂which␈α∂was␈α∞implicit␈α∂in␈α∂the␈α∂previous␈α∂evaluators.␈α∞Those
␈↓ ↓H␈↓evaluators␈α
used␈α
recursion␈α
in␈α
the␈α
explication␈α
of␈α
recursion,␈α
frequently␈α
depended␈α
on␈α
call-by-value␈α
in
␈↓ ↓H␈↓the␈α
explanation␈α
of␈αcall-by-value,␈α
and␈α
suppressed␈αmuch␈α
of␈α
the␈αdetail␈α
of␈α
binding␈αand␈α
look␈α
up.␈αThe
␈↓ ↓H␈↓Weizenbaum␈αenvironments␈αadded␈αmore␈αdetail,␈αbut␈αfailed␈αto␈αdescribe␈αan␈αexplicit␈αmechanism␈αfor␈α
the
␈↓ ↓H␈↓handling␈α
of␈αpartial␈α
computations,␈αneither␈α
showing␈α
where␈αpartial␈α
results␈αwere␈α
maintained␈α
nor␈αhow
␈↓ ↓H␈↓the␈α∀evaluator␈α∀was␈α∀to␈α∀remember␈α∀where␈α∀it␈α∀was␈α∪in␈α∀an␈α∀expression␈α∀when␈α∀it␈α∀had␈α∀to␈α∀evaluate␈α∪a
␈↓ ↓H␈↓sub-expression.␈α
All␈α
of␈αthis␈α
detail␈α
will␈αcome␈α
out␈α
in␈α
the␈αnew␈α
evaluator.␈α
Since␈αthe␈α
structure␈α
of␈αthe␈α
new
␈↓ ↓H␈↓␈↓αeval␈↓␈αis␈αquite␈αdifferent␈αfrom␈αthose␈αwe␈αhave␈αseen␈αbefore,␈αand␈αsince␈αthe␈αlevel␈αof␈αdetail␈αis␈αmore␈α
intense,
␈↓ ↓H␈↓we will proceed in several steps.
␈↓ ↓H␈↓First␈α∩we␈α∩discuss␈α∩some␈α∩generalizations␈α∩of␈α∩the␈α∩label-and-␈↓αgo␈↓␈α∩control␈α∩structures.␈α∩These␈α∩ideas␈α∩have
␈↓ ↓H␈↓importance␈α
in␈α
their␈α
own␈α
right␈α
when␈α
we␈α
discuss␈α
actual␈α
interactive␈α
implementations␈α
of␈α
LISP.␈αNext␈α
we
␈↓ ↓H␈↓develop␈α∂an␈α∂␈↓αeval␈↓␈α∂in␈α∂which␈α∂the␈α∂handling␈α∞of␈α∂access␈α∂structures␈α∂is␈α∂explicit.␈α∂ The␈α∂innovations␈α∂in␈α∞this
␈↓ ↓H␈↓evaluator␈α
will␈α
form␈α
the␈α
basic␈α
blocks␈α
which␈αwe␈α
will␈α
use␈α
to␈α
model␈α
parameter␈α
passing␈αand␈α
assignments.
␈↓ ↓H␈↓This␈αevaluator␈αwill␈αstill␈αbe␈αrecursively␈αdescribed,␈αand␈αwill␈αnot␈αhandle␈αthe␈α␈↓αprog␈↓␈αfeature.␈αIn␈αthe␈αfinal
␈↓ ↓H␈↓step␈α∂we␈α∂replace␈α⊂the␈α∂recursion␈α∂with␈α∂explicit␈α⊂control␈α∂and␈α∂with␈α∂this␈α⊂change␈α∂we␈α∂have␈α∂the␈α⊂basis␈α∂for
␈↓ ↓H␈↓adequate␈αtreatment␈αof␈αnon-recursive␈αcontrol.␈α Finally␈αwe␈αpresent␈αan␈αevaluator␈αwhich␈αhandles␈αall␈αof
␈↓ ↓H␈↓the ␈↓αprog␈↓-related constructs.
␈↓ ↓H␈↓␈↓ ∧V␈↓↓4.5 Non-recursive Control Structures␈↓
␈↓ ↓H␈↓On␈α
page 174␈α
we␈αdiscussed␈α
the␈α
␈↓αgo␈↓␈α
construct.␈αIn␈α
that␈α
discussion␈αwe␈α
noted␈α
that␈α
the␈αscope␈α
of␈α
the␈α␈↓αgo␈↓␈α
was
␈↓ ↓H␈↓not␈α⊂restricted␈α⊃to␈α⊂the␈α⊃current␈α⊂␈↓αprog␈↓;␈α⊂we␈α⊃need␈α⊂only␈α⊃locate␈α⊂an␈α⊂appropriate␈α⊃label␈α⊂in␈α⊃a␈α⊂␈↓↓dynamically␈↓
␈↓ ↓H␈↓surrounding␈α∃expression.␈α∀Thus␈α∃we␈α∀could␈α∃jump␈α∀out␈α∃of␈α∀an␈α∃expression,␈α∀passing␈α∃through␈α∀many
␈↓ ↓H␈↓intervening␈α∪expressions,␈α∪whereas␈α∀strict␈α∪recursive␈α∪control␈α∪requires␈α∀that␈α∪we␈α∪exit␈α∪functions␈α∀in␈α∪a
␈↓ ↓H␈↓level-by-level␈αfashion.␈α This␈αability␈α
to␈αexit␈αacross␈αmany␈α
levels␈αof␈αcomputation␈αfinds␈α
applications␈αat
␈↓ ↓H␈↓the␈αsystem␈αlevel␈α
in␈αinteractive␈αLISP␈αimplementations␈α
and␈αis␈αalso␈α
a␈αuseful␈αprogramming␈αfeature.␈α
For
␈↓ ↓H␈↓example,␈αif␈αsome␈αextraordinary␈αcondition␈αoccurs␈αwithin␈αa␈αcomputation␈αwe␈αmight␈αwish␈αto␈αabort␈αthat
␈↓ ↓H␈↓whole␈α∞endeavor.␈α∂As␈α∞things␈α∂currently␈α∞stand␈α∂we␈α∞would␈α∂have␈α∞to␈α∂supply␈α∞an␈α∂additional␈α∞value␈α∂in␈α∞the
␈↓ ↓H␈↓range␈α
of␈α
each␈α
function␈α
which␈α
could␈α
occur␈α∞in␈α
that␈α
computation.␈α
Each␈α
function␈α
would␈α
have␈α∞to␈α
test
␈↓ ↓H␈↓for␈αthat␈αexception-value␈αand␈αwhen␈αit␈αis␈αfound,␈αreturn␈αthat␈αvalue␈αto␈αthe␈αcaller.␈αThis␈αis␈αan␈αeffective,
␈↓ ↓H␈↓but␈α
not␈αelegant,␈α
solution␈αto␈α
the␈αproblem.␈α
Notice␈αthat␈α
this␈αis␈α
the␈αsolution␈α
posed␈αin␈α
our␈αuse␈α
of␈α
␈↓λB␈↓␈αin
␈↓ ↓H␈↓conjunction␈αwith␈αstrict␈αfunctions.␈α Indeed,␈αa␈αmore␈αelegant␈αsolution␈αhas␈αits␈αorigins␈αin␈αthe␈αearly␈αLISP
␈↓ ↓H␈↓debugging␈αtools.␈αIf␈αa␈αcomputation␈αproduced␈αa␈αdetectable␈αerror,␈αthen␈αit␈αwas␈αthe␈αresponsibility␈αof␈αthe
␈↓ ↓H␈↓LISP␈α⊃controller␈α⊃to␈α⊃print␈α⊃an␈α⊃error␈α⊂message␈α⊃and␈α⊃terminate␈α⊃the␈α⊃computation.␈α⊃Such␈α⊃behavior␈α⊂was
␈↓ ↓H␈↓␈↓↓184 Imperative Constructs in LISP␈↓ 14.5␈↓
␈↓ ↓H␈↓acceptable␈αfor␈α
simple␈αcomputations.␈α
As␈αcomputations␈α
became␈αmore␈α
complex␈αit␈α
became␈αclear␈αthat␈α
the
␈↓ ↓H␈↓occurrence␈αof␈α
one␈αerror␈α
need␈αnot␈α
signal␈αthe␈αtermination␈α
of␈α␈↓↓all␈↓␈α
computation.␈α Particularly␈α
since␈αthe
␈↓ ↓H␈↓expressions␈α
were␈α
available␈α
as␈α
data␈α
structures,␈α
the␈α
opportunity␈α
for␈α
self-correcting␈α
programs␈α
existed␈α
in
␈↓ ↓H␈↓LISP. Thus LISP needed a mechanism for more selective control of error messages.
␈↓ ↓H␈↓The␈α∞early␈α∞LISP␈α∞systems␈α∞supplied␈α∞a␈α∞pair␈α∞of␈α∞functions␈α∞named␈α∞␈↓αerrset␈↓␈α∞and␈α∞␈↓αerr␈↓.␈α∞ The␈α∞function␈α∞␈↓αerrset␈↓
␈↓ ↓H␈↓evaluates␈αits␈αfirst␈αargument␈αin␈αthe␈αcurrent␈αcontext.␈α If␈αno␈αerror␈αoccurs␈αin␈αthat␈αevaluation,␈αthe␈αresult
␈↓ ↓H␈↓is␈α
␈↓αconcat␈↓ed␈α
onto␈α( )␈α
and␈α
returned.␈αIf␈α
an␈α
error␈αdoes␈α
occur␈α
then␈α
the␈αvalue␈α
of␈α
the␈α␈↓αerrset␈↓␈α
is␈α
␈↓
f␈↓.␈αNotice␈α
that
␈↓ ↓H␈↓in␈α
either␈αcase␈α
the␈α
␈↓αerrset␈↓␈αterminates.␈α
We␈α
can␈αtest␈α
the␈α
success␈αof␈α
our␈α
calculation␈αby␈α
sampling␈αthe␈α
value
␈↓ ↓H␈↓of ␈↓αerrset␈↓: ␈↓
f␈↓ implies failure; otherwise the ␈↓αfirst␈↓ element of the result is the true value.
␈↓ ↓H␈↓The␈αuser␈αcan␈αalso␈αforce␈α
the␈αoccurrence␈αof␈αan␈α"error"␈αby␈α
calling␈α␈↓αerr␈↓.␈α The␈αunary␈αfunction␈α␈↓αerr␈↓␈α
returns
␈↓ ↓H␈↓the␈αvalue␈α
of␈αits␈αargument␈α
to␈αthe␈α
dynamically␈αenclosing␈α␈↓αerrset␈↓␈α
or,␈αif␈α
there␈αis␈αno␈α
such␈α␈↓αerrset␈↓,␈αthe␈α
value
␈↓ ↓H␈↓is␈α⊂returned␈α∂as␈α⊂the␈α∂final␈α⊂value␈α∂of␈α⊂the␈α⊂computation.␈α∂For␈α⊂example␈α∂if␈α⊂␈↓αerr␈↓␈α∂is␈α⊂restricted␈α⊂to␈α∂returning
␈↓ ↓H␈↓values␈α
in␈α
a␈α
set␈αdisjoint␈α
from␈α
those␈α
returned␈αby␈α
a␈α
non-"error"␈α
computation,␈αthen␈α
the␈α
user␈α
can␈αtest␈α
the
␈↓ ↓H␈↓value of ␈↓αerrset␈↓ to discover the type of "error".
␈↓ ↓H␈↓The␈α
freedom␈α∞allowed␈α
by␈α∞the␈α
␈↓αerrset-err␈↓␈α∞combination␈α
soon␈α∞became␈α
exploited␈α∞in␈α
ways␈α∞not␈α
originally
␈↓ ↓H␈↓intended.␈α
The␈α
use␈α
of␈α∞␈↓αerrset␈↓␈α
and␈α
␈↓αerr␈↓␈α
in␈α∞non-error-handling␈α
contexts␈α
often␈α
became␈α∞quite␈α
confusing.
␈↓ ↓H␈↓The␈αMacLISP␈α([Moo 74])␈α
dialect␈αincludes␈αa␈α
pair␈αof␈αconstructs␈α
named␈α␈↓αcatch␈↓␈αand␈α
␈↓αthrow␈↓␈αto␈αbe␈αused␈α
in
␈↓ ↓H␈↓these situations.
␈↓ ↓H␈↓␈↓αcatch␈↓␈α⊃and␈α⊃␈↓αthrow␈↓␈α⊃are␈α∩both␈α⊃binary␈α⊃functions.␈α⊃Both␈α∩first␈α⊃arguments␈α⊃are␈α⊃expressions;␈α∩both␈α⊃second
␈↓ ↓H␈↓arguments are interpreted like ␈↓αprog␈↓ labels.
␈↓ ↓H␈↓␈↓αcatch␈↓[<form>;<label>]␈α∂evaluates␈α∂its␈α∂first␈α∞argument␈α∂in␈α∂the␈α∂current␈α∞context,␈α∂and␈α∂returns␈α∂that␈α∞value,
␈↓ ↓H␈↓except␈α
that␈α
if␈αduring␈α
that␈α
evaluation,␈αa␈α
␈↓αthrow[␈↓<form>;<label>]␈α
with␈αthe␈α
same␈α
<label>␈α
is␈αevaluated,
␈↓ ↓H␈↓then the value of ␈↓αthrow␈↓'s <form> is returned immediately.
␈↓ ↓H␈↓For example␈↓π 133␈↓:
␈↓ ↓H␈↓α␈↓ βxcatch[␈↓ ∧Hmapfirst[␈↓ ¬Hfunction[λ[[x][x<0 → throw[x;negative];␈↓
t␈↓α → f[x]]]];
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧H␈↓ ¬Hy];
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧Hnegative]
␈↓ ↓H␈↓Assuming␈α␈↓αy␈↓␈αis␈αa␈αlist␈αof␈αnumbers,␈αthis␈αexpression␈αwill␈αreturn␈αa␈αlist␈αof␈α␈↓αf␈↓␈αapplied␈αto␈αeach␈αelement␈αof␈α␈↓αy␈↓
␈↓ ↓H␈↓if each element of ␈↓αy␈↓ is non-negative, otherwise it will return the first negative element of ␈↓αy␈↓.
␈↓ ↓H␈↓The␈α
␈↓αcatch-throw␈↓␈α
pair␈α
are␈α
the␈α
control␈α
analog␈α
of␈α
the␈α
␈↓αfunction-funarg␈↓ application␈α
pair␈α
for␈α
access.␈α
A
␈↓ ↓H␈↓general␈α
implementation␈αof␈α
␈↓αcatch-throw␈↓␈αintroduces␈α
a␈αvery␈α
non-recursive␈αcontrol␈α
regime.␈α
The␈αususal
␈↓ ↓H␈↓implementation␈α∪corresponds␈α∪to␈α∪allowing␈α∩functional␈α∪␈↓↓arguments␈↓␈α∪only;␈α∪if␈α∩we␈α∪wish␈α∪to␈α∪␈↓αthrow␈↓␈α∩into
␈↓ ↓H␈↓procedure␈α⊃activations␈α⊂which␈α⊃have␈α⊂already␈α⊃been␈α⊂exited,␈α⊃then␈α⊂we␈α⊃must␈α⊂implement␈α⊃a␈α⊃control␈α⊂tree
␈↓ ↓H␈↓similar␈α
to␈αthat␈α
discussed␈αfor␈α
functional␈αvalues.␈α
The␈αnext␈α
few␈αsections␈α
will␈α
develop␈αimplementation
␈↓ ↓H␈↓techniques which will support such tree-like implementations.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 133␈↓ [Moo 74]
␈↓ ↓H␈↓␈↓↓4.6␈↓ λ(␈↓αeval␈↓↓ with Explicit Access 185␈↓α
␈↓ ↓H␈↓␈↓ ¬
␈↓↓4.6 ␈↓αeval␈↓↓ with Explicit Access␈↓α
␈↓ ↓H␈↓There␈α⊃are␈α⊃two␈α⊃major␈α⊃portions␈α⊃of␈α⊃the␈α⊃evaluation␈α⊃schemes␈α⊃which␈α⊃should␈α⊃be␈α⊃subjected␈α⊃to␈α⊃closer
␈↓ ↓H␈↓scrutiny␈α
before␈α∞we␈α
attempt␈α
to␈α∞discuss␈α
implementations:␈α∞the␈α
access␈α
and␈α∞binding␈α
structures,␈α∞and␈α
the
␈↓ ↓H␈↓description of recursive control. This section will look at access and binding.
␈↓ ↓H␈↓The␈αWeizenbaum␈αenvironments␈αgive␈αa␈αnice␈αgraphical␈αrepresentation␈αof␈αthe␈αaccess␈αstructures,␈αbut␈αit
␈↓ ↓H␈↓would␈α∞be␈α∂instructive␈α∞to␈α∞express␈α∂these␈α∞ideas␈α∂in␈α∞terms␈α∞of␈α∂LISP␈α∞functions.␈α∞ This␈α∂would␈α∞give␈α∂us␈α∞an
␈↓ ↓H␈↓algorithm,␈α∂suitable␈α⊂for␈α∂implementation,␈α⊂and␈α∂would␈α⊂describe␈α∂the␈α⊂mechanisms␈α∂of␈α⊂LISP␈α∂at␈α⊂a␈α∂more
␈↓ ↓H␈↓detailed␈αlevel␈α
than␈αthat␈α
in␈αthe␈α
evaluators␈αof␈α
Section 3.5.␈αThe␈α
description␈αwe␈α
will␈αgive␈α
will␈αinvolve
␈↓ ↓H␈↓primitive␈αnotions␈αjust␈αas␈αthe␈αprior␈α␈↓αeval␈↓'s␈αdo,␈αhowever␈αthe␈αlevel␈αof␈αdetail␈αwhich␈αthey␈αcapture␈αwill␈αbe
␈↓ ↓H␈↓more␈α∀readily␈α∃transcribed␈α∀to␈α∀implementation␈α∃devices.␈α∀ As␈α∀we␈α∃have␈α∀previously␈α∃mentioned,␈α∀the
␈↓ ↓H␈↓Weizenbaum␈α
environments␈α
leave␈α
much␈α
of␈α
the␈α
detail␈αof␈α
access␈α
and␈α
binding␈α
implicit.␈α
It␈α
will␈α
be␈αa␈α
goal
␈↓ ↓H␈↓of this section to fill in these details.
␈↓ ↓H␈↓Recall␈α
that␈α
a␈α∞Weizenbaum␈α
environment␈α
was␈α∞created␈α
at␈α
function-entry␈α∞time.␈α
As␈α
we␈α∞evaluated␈α
the
␈↓ ↓H␈↓arguments␈α⊃to␈α⊃a␈α⊂function,␈α⊃we␈α⊃saved␈α⊃the␈α⊂results␈α⊃in␈α⊃some␈α⊃fashion␈α⊂and,␈α⊃when␈α⊃all␈α⊃arguments␈α⊂were
␈↓ ↓H␈↓evaluated␈αwe␈αformed␈αa␈αnew␈αlocal␈αblock,␈αlinking␈αit␈αon␈αto␈αthe␈αfront␈αof␈αthe␈αexisting␈αenvironment,␈αand
␈↓ ↓H␈↓the␈αresulting␈αstructure␈αbecame␈αthe␈αnew␈αenvironment.␈αSince␈αwe␈αneed␈αspace␈αto␈αcontain␈αthe␈αevaluated
␈↓ ↓H␈↓parameters,␈α∂and␈α∂since␈α∞those␈α∂results␈α∂are␈α∂then␈α∞moved␈α∂into␈α∂a␈α∂environment␈α∞block,␈α∂we␈α∂might␈α∂as␈α∞well
␈↓ ↓H␈↓make␈αthe␈αspace␈αwhich␈αis␈αto␈αcontain␈αthose␈αevaluated␈αparameters␈αas␈αmuch␈αlike␈αan␈αenvironment␈αblock
␈↓ ↓H␈↓as␈αpossible.␈α The␈α
space␈αrequirements␈αfor␈αthe␈α
evaluated␈αparameters␈αis␈αknown:␈α
the␈αblock␈αmust␈α
be␈αas
␈↓ ↓H␈↓long␈α∩as␈α∩the␈α∩number␈α⊃of␈α∩formal␈α∩parameters␈α∩expected.␈α⊃ This␈α∩requirement␈α∩can␈α∩be␈α∩ascertained␈α⊃by
␈↓ ↓H␈↓examining␈α⊃the␈α⊃definition␈α⊃of␈α∩the␈α⊃function␈α⊃being␈α⊃called.␈α⊃Once␈α∩the␈α⊃block␈α⊃is␈α⊃allocated,␈α∩the␈α⊃actual
␈↓ ↓H␈↓parameters␈αare␈αevaluated␈αand␈αthe␈α
results␈αare␈αsent␈αto␈αthe␈αproper␈α
slot␈αin␈αthe␈αallocated␈αblock.␈α
Such␈αa
␈↓ ↓H␈↓block␈αwill␈αbe␈αcalled␈αa␈α␈↓↓destination␈αblock␈↓;␈αand␈αthe␈αoperation␈αof␈αplacing␈αa␈αresult␈αin␈αa␈αdestination␈αwill
␈↓ ↓H␈↓be␈αcalled␈α␈↓↓sending␈↓.␈α Once␈αall␈αthe␈αevaluated␈αparameters␈αhave␈αbeen␈αsent,␈αwe␈α␈↓↓link␈↓␈αthe␈αcompleted␈αblock
␈↓ ↓H␈↓into␈α_the␈α↔front␈α_of␈α_the␈α↔current␈α_environment.␈α_ The␈α↔ideas␈α_expressed␈α_in␈α↔this␈α_section␈α_are␈α↔an
␈↓ ↓H␈↓embellishment␈α∀of␈α∪those␈α∀on␈α∪page 109.␈α∀ The␈α∪innovation␈α∀is␈α∪to␈α∀allocate␈α∪space␈α∀for␈α∀the␈α∪evaluated
␈↓ ↓H␈↓arguments␈α
before␈α
beginning␈αtheir␈α
actual␈α
evaluation.␈αThe␈α
evaluator␈α
sends␈αthe␈α
values␈α
to␈αthe␈α
allocated
␈↓ ↓H␈↓block.
␈↓ ↓H␈↓Here are the primitive routines:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α∂␈↓αalloc_dest␈↓:␈α∂This␈α∂unary␈α∂function␈α∂is␈α∂supplied␈α∂with␈α∂the␈α∂formal␈α∂parameter␈α∂list␈α∂of␈α∂a␈α∂function,␈α∞and
␈↓ ↓H␈↓␈↓ αxsupplies␈α→a␈α_new␈α→destination␈α→block␈α_with␈α→the␈α→formal␈α_parameters␈α→placed␈α→in␈α_the
␈↓ ↓H␈↓␈↓ αxname-section␈α∂of␈α∂the␈α∂block.␈α∂An␈α∂internal␈α∂pointer␈α∂is␈α∂initialized␈α∂to␈α∂the␈α∂first␈α∂slot␈α∂in␈α∂the
␈↓ ↓H␈↓␈↓ αxblock. Thus:
␈↓ ↓H␈↓␈↓↓186 Imperative Constructs in LISP␈↓ 24.6␈↓
␈↓"␈↓ ↓H␈↓
␈↓ a destination block␈↓
␈↓"␈↓ ↓H␈↓
⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
~ #αβα⊃
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ ␈↓internal pointer␈↓
␈↓"␈↓ ↓H␈↓
~ ~ ~←$
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~
␈↓"␈↓ ↓H␈↓
# # #
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
↑ ↑
␈↓"␈↓ ↓H␈↓
␈↓formal parameters values␈↓
␈↓ ↓H␈↓␈↓↓2.␈↓␈α∞␈↓αsend␈↓:␈α
This␈α∞is␈α
a␈α∞binary␈α
function␈α∞whose␈α∞first␈α
argument␈α∞is␈α
a␈α∞destination␈α
block␈α∞and␈α∞whose␈α
second
␈↓ ↓H␈↓␈↓ α8argument␈α
is␈α
a␈αvalue␈α
to␈α
be␈αsent.␈α
The␈α
value␈α
of␈α␈↓αsend␈↓␈α
is␈α
the␈αdestination␈α
block.␈α
The␈α
effect␈αof
␈↓ ↓H␈↓␈↓ α8␈↓αsend␈↓␈αis␈αto␈αsend␈αits␈αsecond␈αargument␈αto␈αthe␈αcurrent␈αdestination␈αslot.␈αThe␈αinternal␈αpointer␈αis
␈↓ ↓H␈↓␈↓ α8␈↓↓not␈↓ updated; that is the business of ␈↓αnext␈↓.
␈↓ ↓H␈↓␈↓↓3.␈↓␈α␈↓αnext␈↓:␈αThis␈αfunction␈αtakes␈αa␈αdestination␈αblock␈αas␈αargument␈αand␈αmoves␈αthe␈αinternal␈αpointer␈αof␈αthe
␈↓ ↓H␈↓␈↓ α8block␈αto␈αpoint␈αto␈αthe␈αsucceeding␈αslot.␈αThe␈α
value␈αof␈α␈↓αnext␈↓␈αis␈αthe␈αdestination␈αblock.␈αThus␈α
␈↓αnext␈↓
␈↓ ↓H␈↓␈↓ α8is an identity function with a side-effect.
␈↓ ↓H␈↓␈↓↓4.␈↓␈α␈↓αlink␈↓:␈α␈↓αlink␈↓␈αtakes␈αa␈αdestination␈αblock␈α
and␈αan␈αenvironment␈αas␈αarguments␈αand␈αlinks␈α
the␈αdestination
␈↓ ↓H␈↓␈↓ α8block␈α
onto␈α
the␈α
front␈α
of␈α
the␈α
environment.␈αThe␈α
resulting␈α
environment␈α
is␈α
the␈α
value␈α
of␈α␈↓αlink␈↓.
␈↓ ↓H␈↓␈↓ α8Since␈αthe␈αinternal␈αpointer␈αis␈αonly␈αused␈αduring␈αthe␈αfilling␈αof␈αthe␈αdest-block,␈αwe␈αcan␈αassume
␈↓ ↓H␈↓␈↓ α8that ␈↓αlink␈↓ replaces that pointer with a pointer to the previous environment.
␈↓ ↓H␈↓␈↓↓5.␈↓␈α␈↓αreceive␈↓:␈αSometimes␈αwe␈αwill␈αwish␈αto␈αexamine␈αthe␈αresult␈αof␈αa␈αcomputation␈αbefore␈αmaking␈αa␈α
decision
␈↓ ↓H␈↓␈↓ αHon␈α∀how␈α∀to␈α∪proceed.␈α∀In␈α∀particular,␈α∪in␈α∀conditional␈α∀expressions␈α∪we␈α∀must␈α∀evaluate␈α∪the
␈↓ ↓H␈↓␈↓ αHpredicate␈α
position␈αbefore␈α
knowing␈αhow␈α
to␈αhandle␈α
the␈αrest␈α
of␈αthe␈α
conditional.␈α
The␈αunary
␈↓ ↓H␈↓␈↓ αHprimitive␈α␈↓αreceive␈↓␈αlets␈αus␈αlook␈αat␈αthe␈αresult␈αof␈αa␈αcomputation.␈αThe␈αargument␈αto␈α␈↓αreceive␈↓␈αis␈αa
␈↓ ↓H␈↓␈↓ αHdestination block, and the value returned is the value in the current slot.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓Give␈α≥a␈α≡full␈α≥LISP␈α≥representation␈α≡of␈α≥destination␈α≥blocks␈α≡and␈α≥supply␈α≡the␈α≥corresponding
␈↓ ↓H␈↓implementations for the primitive routines, ␈↓↓1␈↓ through ␈↓↓5␈↓.
␈↓ ↓H␈↓␈↓↓4.6␈↓ λ(␈↓αeval␈↓↓ with Explicit Access 187␈↓α
␈↓ ↓H␈↓In␈α_the␈α_following␈α→evaluators␈α_we␈α_will␈α_freely␈α→use␈α_the␈α_extended␈α_conditional␈α→expressions␈α_and
␈↓ ↓H␈↓λ-expressions␈αintroduced␈αon␈αpage 180␈αand␈αpage 182.␈α
The␈αfirst␈αevaluator␈αis␈αnamed␈α␈↓αdeval␈↓,␈α
with␈αthe
␈↓ ↓H␈↓"␈↓αd␈↓ coming from "destination".
␈↓ ↓H␈↓αdeval <= λ[[exp;env;dest]
␈↓ ↓H␈↓α␈↓ β([isconst[exp] → send[dest;denote[exp]];
␈↓ ↓H␈↓α␈↓ β( isvar[exp] → send[dest;lookup[exp;env]];
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → deval␈↓β1␈↓α[func[exp]; arglist[exp]; env; dest] ]]
␈↓ ↓H␈↓αdeval␈↓β1␈↓α <= λ[[fun;args;env;dest]
␈↓ ↓H␈↓α␈↓ β([atom[fun] →␈↓ ∧h[iscond[fun] → devcond[args;env;dest]
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h isprim[fun] → execute[␈↓ π_fun;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h␈↓ ελ␈↓ π_link[␈↓ πhevalargs[␈↓ λXargs;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h␈↓ ελ␈↓ π_␈↓ πh␈↓ λXenv;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h␈↓ ελ␈↓ π_␈↓ πh␈↓ λXalloc_dest[createvars[args]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h␈↓ ελ␈↓ π_␈↓ πhenv];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h␈↓ ελ␈↓ π_dest];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h ␈↓
t␈↓α → deval[fun;env;dest]; deval␈↓β1␈↓α[receive[dest];args;env;dest] ]
␈↓ ↓H␈↓α␈↓ β( islambda[fun] → evalargs[␈↓ ελbodylist[fun];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h␈↓ ελlink[evalargs[args;env;alloc_dest[vars[fun]]]];env];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧h␈↓ ελdest]
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → deval[fun;env;dest]; deval␈↓β1␈↓α[receive[dest];args;env;dest] ]]
␈↓ ↓H␈↓αevalargs <= λ[[args;env;dest]
␈↓ ↓H␈↓α␈↓ β([null[args] →dest;
␈↓ ↓H␈↓α␈↓ β( null[rest[args]] → deval[first[args];env;dest];
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → deval[␈↓ ∧8first[args];env;dest];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧8next[dest];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧8evalargs[rest[args];env;dest] ]]
␈↓ ↓H␈↓αexecute <= λ[[fun;env;dest]send[dest;apply[fun;vals[env];( )]]]
␈↓ ↓H␈↓Note that ␈↓αexecute␈↓ resorts to ␈↓αapply␈↓ to handle primitive application.
␈↓ ↓H␈↓αdevcond <= λ[[args;env;dest]
␈↓ ↓H␈↓α␈↓ β(deval[pred[first[args]];env;dest];
␈↓ ↓H␈↓α␈↓ β([receive[dest] → evalargs[condbody[first[args]];env;dest];
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → devcond[rest[args]; env;dest] ]]
␈↓ ↓H␈↓␈↓↓188 Imperative Constructs in LISP␈↓ 24.6␈↓
␈↓ ↓H␈↓This␈αnew␈αevaluator␈αmust␈αbe␈αsupplied␈αwith␈αan␈αinitial␈αdestination␈αas␈αwell␈αas␈αbeing␈αsupplied␈αwith␈αan
␈↓ ↓H␈↓initial␈α
symbol␈α
table.␈α
Also,␈α
since␈αthe␈α
result␈α
of␈α
any␈α
calculation␈α
is␈αa␈α
destination␈α
block␈α
rather␈α
than␈αjust␈α
a
␈↓ ↓H␈↓simple␈αvalue,␈αwe␈αshould␈αsupply␈αa␈αselector␈αto␈αextract␈αthe␈αdesired␈αvalue.␈αFor␈αexample,␈αif␈αwe␈αdesignate
␈↓ ↓H␈↓␈↓αval␈↓ as such a selector, and designate the atom ␈↓αTLB␈↓ as the repository for the top level binding then:
␈↓ ↓H␈↓α␈↓ β]eval <= λ[[exp;env] val[deval[exp;env;alloc_dest[(TLB)]]]]
␈↓ ↓H␈↓More␈α∪of␈α∪the␈α∀details␈α∪of␈α∪argument␈α∀handling␈α∪should␈α∪now␈α∀be␈α∪understandable:␈α∪when␈α∀a␈α∪function
␈↓ ↓H␈↓application␈αhas␈αbeen␈αrecognized,␈αthe␈αevaluator␈αsets␈αup␈αa␈αblock␈αto␈αhold␈αthe␈αresults␈αof␈αevaluating␈αthe
␈↓ ↓H␈↓actual␈αparameters.␈αIf␈α
the␈αfunction␈αis␈α
a␈αprimitive␈αfunction␈α
then␈αthe␈αname␈α
slots␈αare␈αfilled␈α
with␈αsome
␈↓ ↓H␈↓system-created names, otherwise the λ-variables are used.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓␈↓ αCUsing the new evaluator, sketch the evaluation of ␈↓αf[A]␈↓ where: ␈↓αf <= λ[[x] eq[x;A]]␈↓.
␈↓ ↓H␈↓Notice␈α
that␈α
for␈α
most␈α
of␈αthe␈α
evaluation␈α
process,␈α
␈↓αdest␈↓␈α
is␈α
a␈αpassive␈α
element.␈α
A␈α
new␈α
destination␈αblock␈α
is
␈↓ ↓H␈↓created␈α
on␈α
function␈α
applications,␈α
but␈α
that␈α
␈↓αdest␈↓␈α
is␈α
passed␈α
around␈α
as␈α
an␈α
argument␈α
through␈α∞most␈α
of
␈↓ ↓H␈↓the␈α
pieces␈α∞of␈α
the␈α∞evaluator␈α
without␈α∞explicit␈α
modification.␈α
That␈α∞is,␈α
in␈α∞most␈α
λ-bindings␈α∞␈↓αdest␈↓␈α
simply
␈↓ ↓H␈↓gets␈αbound␈αto␈α␈↓αdest␈↓.␈α Since␈αthe␈αλ-binding␈αprocess␈αis␈αnot␈αinexpensive␈αit␈αis␈αtempting␈αto␈αmake␈αvariables
␈↓ ↓H␈↓like␈α⊃␈↓αdest␈↓,␈α⊃which␈α⊃change␈α⊃infrequently,␈α⊃into␈α⊃non-local␈α⊃variables;␈α⊃they␈α⊃would␈α⊃be␈α⊃initialized␈α⊃at␈α⊂the
␈↓ ↓H␈↓outside␈α∞layer␈α∂and␈α∞modified␈α∞by␈α∂side-effects␈α∞during␈α∂the␈α∞evaluation.␈α∞ However␈α∂the␈α∞current␈α∂value␈α∞of
␈↓ ↓H␈↓␈↓αdest␈↓␈α
␈↓↓does␈↓␈α
need␈α
to␈α
be␈α
saved␈α
occasionally.␈αThose␈α
occasions␈α
correspond␈α
to␈α
the␈α
places␈α
where␈α
␈↓αdest␈↓␈αgets
␈↓ ↓H␈↓rebound␈α
to␈α
something␈α
other␈α
than␈α
␈↓αdest␈↓.␈α
We␈α
will␈α
supply␈α
two␈α
new␈α
primitives␈α
to␈α
handle␈αexplicit␈α
saving
␈↓ ↓H␈↓and restoring of values:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α␈↓αsave␈↓:␈α
This␈αbinary␈αfunction␈α
would␈αbe␈αimplemented␈α
as␈αa␈αspecial␈α
form.␈α Its␈αfirst␈α
argument␈αis␈αa␈α
name
␈↓ ↓H␈↓␈↓ α(␈↓αold␈↓,␈α
and␈αits␈α
second␈α
argument␈αis␈α
a␈αvalue␈α
␈↓αnew␈↓.␈α
The␈αcurrent␈α
value␈α
associated␈αwith␈α
␈↓αold␈↓␈αis␈α
saved,
␈↓ ↓H␈↓␈↓ α(and the value ␈↓αnew␈↓ becomes the value of ␈↓αold␈↓.
␈↓ ↓H␈↓␈↓↓2.␈↓␈α␈↓αrestore␈↓:␈α
This␈αis␈α
a␈αunary␈α
function;␈αits␈α
argument␈αis␈α
a␈αname␈α
␈↓αname␈↓.␈αThe␈α
latest␈αvalue␈α
which␈αwas␈α
saved
␈↓ ↓H␈↓␈↓ αHfor ␈↓αname␈↓ is restored. The value which ␈↓αname␈↓ had on entry to ␈↓αrestore␈↓ is lost.
␈↓ ↓H␈↓Using ␈↓αsave␈↓ and ␈↓αrestore␈↓ we could express the evaluation of a λ-application something like:
␈↓ ↓H␈↓α␈↓ αXeval[␈↓
R␈↓∞(␈↓α λ[[x;y]␈↓λx␈↓α][a;b] ␈↓∞)␈↓α; env] =␈↓ ελsave[x;a];
␈↓ ↓H␈↓α␈↓ αX␈↓ ελsave[y;b];
␈↓ ↓H␈↓α␈↓ αX␈↓ ελeval[␈↓
R␈↓∞( ␈↓λx ␈↓∞)␈↓α ;env␈↓λ'␈↓α];
␈↓ ↓H␈↓α␈↓ αX␈↓ ελrestore[y];
␈↓ ↓H␈↓α␈↓ αX␈↓ ελrestore[x];
␈↓ ↓H␈↓The␈α⊂implementation␈α⊂details␈α⊂of␈α⊂␈↓αsave␈↓␈α⊂and␈α⊂␈↓αrestore␈↓␈α⊃will␈α⊂not␈α⊂be␈α⊂needed␈α⊂for␈α⊂most␈α⊂of␈α⊃our␈α⊂discussion,
␈↓ ↓H␈↓however␈α⊂we␈α⊂include␈α∂some␈α⊂of␈α⊂them␈α⊂here␈α∂for␈α⊂completeness.␈α⊂The␈α∂information␈α⊂which␈α⊂is␈α⊂␈↓αsave␈↓d␈α∂and
␈↓ ↓H␈↓␈↓αrestore␈↓d␈α⊂is␈α⊂accessible␈α∂through␈α⊂a␈α⊂global␈α∂variable␈α⊂named␈α⊂␈↓αcontrol␈↓.␈α∂A␈α⊂␈↓αsave[␈↓<name>;<value>]␈α⊂has␈α∂the
␈↓ ↓H␈↓␈↓↓4.6␈↓ λ(␈↓αeval␈↓↓ with Explicit Access 189␈↓α
␈↓ ↓H␈↓effect␈αof␈α
␈↓αconcat␈↓-ing␈αthe␈αcurrent␈α
value␈αof␈α
<name>␈αonto␈αthe␈α
front␈αof␈α
␈↓αcontrol␈↓;␈αit␈αthen␈α
sets␈αthe␈αnew␈α
value
␈↓ ↓H␈↓of <name> to <value>.
␈↓ ↓H␈↓That is: ␈↓ β␈↓αcontrol ← concat[eval[␈↓<name>␈↓α;env];control];set[␈↓<name>; ␈↓αeval[␈↓<value>␈↓α;env]␈↓
␈↓ ↓H␈↓A ␈↓αrestore␈↓[<name>] performs:
␈↓ ↓H␈↓α␈↓ ∧≡set␈↓[<name>␈↓α;first[control]]; control ← rest[control]
␈↓ ↓H␈↓The␈α∞manipulation␈α
of␈α∞␈↓αcontrol␈↓␈α∞by␈α
␈↓αsave␈↓␈α∞and␈α∞␈↓αrestore␈↓␈α
is␈α∞stack-like␈α
in␈α∞LISP.␈α∞That␈α
means␈α∞that␈α∞only␈α
the
␈↓ ↓H␈↓␈↓αfirst␈↓␈αelement␈αof␈α␈↓αcontrol␈↓␈αis␈αaccessible;␈αto␈αaccess␈αelements␈αin␈αthe␈αinterior␈αof␈α␈↓αcontrol␈↓␈αrequires␈α␈↓αrestore␈↓-ing
␈↓ ↓H␈↓down␈α
to␈α
them␈α
by␈α
sequence␈α
of␈α
"␈↓αcontrol␈↓ ← ␈↓αrest[control]␈↓".␈α
Once␈α
we␈α
have␈α
removed␈α
elements␈αfrom␈α
␈↓αcontrol␈↓
␈↓ ↓H␈↓there␈α
is␈α
no␈αway␈α
to␈α
access␈αthat␈α
information␈α
again.␈α The␈α
␈↓αcontrol␈↓-structure␈α
is␈αnot␈α
accessible␈α
as␈α
a␈αdata
␈↓ ↓H␈↓structure␈α∪to␈α∪the␈α∀same␈α∪degree␈α∪of␈α∪generality␈α∀as␈α∪is␈α∪the␈α∪access␈α∀structure.␈α∪The␈α∪closest␈α∀analogy␈α∪to
␈↓ ↓H␈↓␈↓αfunction-funarg␈↓␈α⊃is␈α⊃the␈α∩␈↓αcatch-throw␈↓␈α⊃pair.␈α⊃However␈α∩now␈α⊃that␈α⊃␈↓αcontrol␈↓␈α⊃␈↓↓is␈↓␈α∩explicit␈α⊃we␈α⊃can␈α∩begin␈α⊃to
␈↓ ↓H␈↓describe extensions to LISP which ␈↓↓will␈↓ allow us to capture ␈↓αcontrol␈↓ like ␈↓αfunction␈↓ captures ␈↓αenv␈↓.
␈↓ ↓H␈↓Given␈α␈↓αsave␈↓␈αand␈α␈↓αrestore␈↓␈α
we␈αcan␈αrewrite␈α␈↓αdeval␈↓␈αand␈α
its␈αsubfunctions␈αto␈αaccess␈αnon-local␈α
representations
␈↓ ↓H␈↓of␈αvariables␈αused␈αin␈αthe␈αcurrent␈α␈↓αdeval␈↓.␈α Thus␈αthe␈αevaluator␈αbecomes␈αa␈αfunction␈αof␈αno␈αarguments;␈αit
␈↓ ↓H␈↓␈↓↓knows␈↓␈αwhere␈αto␈αfind␈αthe␈αvalues␈αand␈αit␈αknows␈αhow␈αto␈αsave␈αand␈αrestore␈αthose␈αvariables.␈α The␈αresult
␈↓ ↓H␈↓is an evaluator which has even ␈↓↓fewer␈↓ implict operations than ␈↓αdeval␈↓.
␈↓ ↓H␈↓αdeval␈↓λ'␈↓α <= λ[[]␈↓ βλ[isconst[] → send[denote[]];
␈↓ ↓H␈↓α␈↓ βλ isvar[] → send[lookup[]];
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α →␈↓ βHsave[fun;func[]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ βHsave[args;arglist[]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ βHdeval␈↓β1␈↓α[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ βHrestore[args];
␈↓ ↓H␈↓α␈↓ βλ␈↓ βHrestore[fun] ]]
␈↓ ↓H␈↓Before␈α
continuing,␈α
a␈α
few␈α
points␈α∞should␈α
be␈α
made.␈α
We␈α
will␈α
be␈α∞using␈α
the␈α
same␈α
names␈α
as␈α
we␈α∞did␈α
in
␈↓ ↓H␈↓␈↓αdeval␈↓␈α∂for␈α∂all␈α∂subfunctions␈α∂of␈α∞␈↓αdeval␈↓λ'␈↓.␈α∂The␈α∂difference␈α∂will␈α∂be␈α∞that␈α∂here␈α∂those␈α∂functions␈α∂will␈α∞␈↓↓know␈↓
␈↓ ↓H␈↓where␈αtheir␈α
arguments␈αare␈α
to␈αbe␈αfound;␈α
they␈αneed␈α
not␈αbe␈αexplicitly␈α
passed␈αin.␈α
Thus␈α␈↓αsend[denote[]]␈↓
␈↓ ↓H␈↓means␈αthat␈α
␈↓αdenote␈↓␈αextracts␈αa␈α
value␈αfrom␈α
the␈αrepresentation␈αin␈α
␈↓αexp␈↓␈αand␈α
␈↓αsend␈↓␈αknows␈αthat␈α
it␈αis␈αto␈α
send
␈↓ ↓H␈↓its value to ␈↓αdest␈↓.
␈↓ ↓H␈↓With this new evaluator we can define ␈↓αeval␈↓ as:
␈↓ ↓H␈↓α␈↓ β(eval <= λ[[x;y]␈↓ ∧xfun ← ();
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧xargs ← ();
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧xexp ← x;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧xenv ← y;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧xdest ← alloc_dest[(TLB)];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧xdeval␈↓λ'␈↓α[];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧xval[dest]]
␈↓ ↓H␈↓␈↓↓190 Imperative Constructs in LISP␈↓ 24.6␈↓
␈↓ ↓H␈↓α␈↓Here is the remainder of ␈↓αdeval␈↓λ'␈↓:
␈↓ ↓H␈↓αdeval␈↓β1␈↓α <= λ[[]␈↓ βλ[isatom[] →␈↓ ∧8[iscond[] → devcond[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8 isprim[] →␈↓ ¬Hsave[env;env];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬Hsave[dest;alloc_dest[createvars[]]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬Hevalargs[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬Hlink[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬Hrestore[dest];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬Hexecute[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬Hrestore[env];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8 ␈↓
t␈↓α → deval␈↓β2␈↓α[] ]
␈↓ ↓H␈↓α␈↓ βλislambda[] →␈↓ ∧8save[env;env];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8save[dest;alloc_dest[vars[]]
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8evalargs[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8link[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8restore[dest];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8save[args;bodylist[]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8evalargs[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8restore[args];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8restore[env];
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α → deval␈↓β2␈↓α[] ]]
␈↓ ↓H␈↓αdeval␈↓β2␈↓α <= λ[[ ]␈↓ β_save[exp;fun];
␈↓ ↓H␈↓α␈↓ β_deval␈↓λ'␈↓α[];
␈↓ ↓H␈↓α␈↓ β_restore[exp];
␈↓ ↓H␈↓α␈↓ β_save[fun;receive[]];
␈↓ ↓H␈↓α␈↓ β_deval␈↓β1␈↓α[];
␈↓ ↓H␈↓α␈↓ β_restore[fun] ]
␈↓ ↓H␈↓We␈α
introduced␈α
␈↓αdeval␈↓β2␈↓␈α
to␈α
capture␈α
the␈α
computation␈α
to␈α
be␈α
performed␈α
when␈α
the␈α
function-position␈αis␈α
not
␈↓ ↓H␈↓recognized␈α⊗as␈α⊗either␈α⊗a␈α⊗λ-expression,␈α⊗a␈α↔conditional,␈α⊗or␈α⊗a␈α⊗primitive.␈α⊗ Note␈α⊗that␈α↔we␈α⊗perform
␈↓ ↓H␈↓␈↓αsave[env;env]␈↓␈α∞in␈α
a␈α∞couple␈α∞of␈α
places␈α∞in␈α∞␈↓αdeval␈↓β1␈↓.␈α
This␈α∞is␈α∞necessary␈α
to␈α∞save␈α∞the␈α
current␈α∞value␈α∞of␈α
␈↓αenv␈↓
␈↓ ↓H␈↓since␈α␈↓αlink␈↓␈αmodifies␈α␈↓αenv␈↓.␈α
Indeed,␈αthe␈αsequence:␈αsave␈α
␈↓αenv␈↓␈αand␈α␈↓αdest␈↓,␈α␈↓αevalargs␈↓,␈α
␈↓αlink␈↓,␈αand␈αrestore␈α␈↓αdest␈↓␈α
can
␈↓ ↓H␈↓be simplified to: save ␈↓αdest␈↓, ␈↓αevalargs␈↓, followed by ␈↓αlink␈↓λ'␈↓. where:
␈↓ ↓H␈↓α␈↓ βYlink␈↓λ'␈↓α <=λ[[] set_int[dest;env];rotate[env;first[control];dest]]
␈↓ ↓H␈↓and␈α␈↓αset_int␈↓␈αsets␈αthe␈αinternal␈αpointer␈αof␈αthe␈αdest-block␈αto␈αthe␈αcurrent␈αenvironment,␈αand␈α␈↓αrotate[x;y;z]␈↓
␈↓ ↓H␈↓moves the contents of ␈↓αx␈↓ to ␈↓αy␈↓, contents of ␈↓αy␈↓ to ␈↓αz␈↓, and contents of ␈↓αz␈↓ to ␈↓αx␈↓.
␈↓ ↓H␈↓␈↓↓4.6␈↓ λ(␈↓αeval␈↓↓ with Explicit Access 191␈↓α
␈↓ ↓H␈↓αevalargs <= λ[[]␈↓ β([emptyargs[] → ( );
␈↓ ↓H␈↓α␈↓ β( singlearg[] →␈↓ ∧Xsave[exp;first[args]];
␈↓ ↓H␈↓α␈↓ β(␈↓ βx␈↓ ∧Xdeval␈↓λ'␈↓α[];
␈↓ ↓H␈↓α␈↓ β(␈↓ βx␈↓ ∧Xrestore[exp];
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α →␈↓ βxsave[exp;first[args]];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxdeval␈↓λ'␈↓α[];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxrestore[exp];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxnext[];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxsave[args;rest[args]];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxevalargs[];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxrestore[args] ]]
␈↓ ↓H␈↓The␈α∂discussions␈α∂surrounding␈α∂this␈α∞evaluator␈α∂tacitly␈α∂assume␈α∂that␈α∞a␈α∂deep␈α∂binding␈α∂strategy␈α∂is␈α∞being
␈↓ ↓H␈↓implemented.␈α∞That␈α∞assumption␈α∞is␈α∞not␈α∞necessary.␈α∞The␈α∞final␈α∞shallow␈α∞binder␈α∞of␈α∞Section 3.11␈α∂can␈α∞be
␈↓ ↓H␈↓incorporated␈αin␈αthe␈αframework␈αof␈αthese␈αlatest␈αevaluators.␈αThe␈αkey␈αalterations␈αinvolve␈αthe␈αrebinding
␈↓ ↓H␈↓of␈αthe␈α
value␈αcells␈α
inside␈α␈↓αdeval␈↓β1␈↓␈α
when␈α␈↓αislambda␈↓␈α
is␈αtrue.␈α
We␈αleave␈α
the␈αmodifications␈α
as␈αa␈αproblem␈α
for
␈↓ ↓H␈↓the reader; and we postpone the treatment of ␈↓αfunction␈↓ until Section 5.19 and Section 5.20.
␈↓ ↓H␈↓Note␈α
also␈αthat␈α
we␈αare␈α
never␈αinterested␈α
in␈α
the␈αvalue␈α
returned␈αfrom␈α
a␈αcall␈α
on␈αa␈α
sub-function␈α
in␈αthe
␈↓ ↓H␈↓evaluator;␈α∂all␈α∞values␈α∂are␈α∞passed␈α∂explicity␈α∞from␈α∂their␈α∞creator␈α∂to␈α∞a␈α∂destination.␈α∞We␈α∂might␈α∂say␈α∞that
␈↓ ↓H␈↓␈↓αdeval␈↓λ'␈↓␈αnever␈αreturns␈αa␈αvalue.␈αIn␈αthe␈αnext␈αsection␈αwe␈αwill␈αbuild␈αan␈αevaluator␈αwhich␈αnever␈αreturns␈αat
␈↓ ↓H␈↓all.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Write the new version of ␈↓αdevcond␈↓.
␈↓ ↓H␈↓II.␈α∂Examine␈α∂the␈α∂␈↓αsave-restore␈↓␈α∂sequences␈α∂in␈α∂␈↓αdeval␈↓λ'␈↓␈α∂and␈α∂its␈α∂sub-functions␈α∂for␈α⊂possible␈α∂inefficiencies.
␈↓ ↓H␈↓That␈α⊃is,␈α⊃are␈α⊃all␈α⊃the␈α⊂saves␈α⊃and␈α⊃restores␈α⊃necessary␈α⊃or␈α⊂could␈α⊃explicit␈α⊃assignments␈α⊃to␈α⊃some␈α⊃of␈α⊂the
␈↓ ↓H␈↓non-local variables speed things up?
␈↓ ↓H␈↓III. Using the new evaluator, sketch the evaluation of ␈↓αf[A]␈↓ where: ␈↓αf <= λ[[x]eq[x;A]]␈↓.
␈↓ ↓H␈↓IV.␈αRevise␈αthe␈αnew␈αevaluator␈αto␈αuse␈αshallow␈αbinding.␈αYou␈αmay␈αrestrict␈αyour␈αsolution␈αto␈αthe␈αcase␈αof
␈↓ ↓H␈↓simple function application without ␈↓αfunction␈↓.
␈↓ ↓H␈↓␈↓↓192 Imperative Constructs in LISP␈↓ 24.7␈↓
␈↓ ↓H␈↓␈↓ ¬β␈↓↓4.7 ␈↓αeval␈↓↓ with Explicit Control␈↓α
␈↓ ↓H␈↓Recursion␈α
and␈α
call-by-value␈α∞are␈α
used␈α
to␈α
guide␈α∞the␈α
flow␈α
of␈α
control␈α∞in␈α
a␈α
LISP␈α
evaluator.␈α∞We␈α
have
␈↓ ↓H␈↓started␈α_to␈α_explore␈α_the␈α_implementation␈α_of␈α_call-by-value,␈α_and␈α_now␈α_we␈α_wish␈α_to␈α_discuss␈α↔the
␈↓ ↓H␈↓implementation␈α
of␈αrecursion.␈α
It␈αis␈α
not␈αnecessary␈α
to␈αunderstand␈α
␈↓↓how␈↓␈αrecursion␈α
works␈α
to␈αunderstand
␈↓ ↓H␈↓recursion;␈αthat␈α
understanding␈α␈↓↓is␈↓␈αnecessary␈α
when␈αwe␈αwish␈α
to␈αimplement␈αit.␈α
The␈αmechanisms␈αused␈α
in
␈↓ ↓H␈↓the␈α
implementation␈α
of␈α
any␈αconcept␈α
must␈α
be␈α
of␈αa␈α
higher␈α
level␈α
of␈αdetail␈α
than␈α
the␈α
mechanism␈αbeing
␈↓ ↓H␈↓implemented.␈α∂ We␈α⊂cannot␈α∂use␈α∂recursion␈α⊂to␈α∂implement␈α∂recursion.␈α⊂The␈α∂basic␈α∂purpose␈α⊂of␈α∂recursive
␈↓ ↓H␈↓control␈αin␈αthe␈αevaluator␈αis␈αto␈αdescribe␈αwhat␈αcomputation␈αto␈αperform␈αnext␈αand␈αto␈αdescribe␈αwhere␈αto
␈↓ ↓H␈↓go␈αwhen␈αfinished.␈αThe␈αevaluator␈αof␈αthis␈αsection␈αwill␈αrely␈αon␈αexplicit␈αdirections␈αto␈αtell␈αit␈αwhat␈αto␈αdo
␈↓ ↓H␈↓next.␈α- The␈α,idea␈α-is␈α,closely␈α-related␈α,to␈α-the␈α,logical␈α-notion␈α-of␈α,␈↓↓continuations␈↓
␈↓ ↓H␈↓([Str 74a], [Rey 72], and [Fis 72])␈αand␈αthus␈αwe␈αwill␈αuse␈αthat␈αterminology␈αhere.␈α In␈αthe␈αevaluators␈αof
␈↓ ↓H␈↓this␈αsection␈αwe␈α
will␈αuse␈αthe␈αdestination␈α
to␈αtell␈αwhere␈α
the␈αresult␈αof␈αthe␈α
current␈αcomputation␈αis␈α
to␈αbe
␈↓ ↓H␈↓put, and use the continuation to tell what the next computation will be.
␈↓ ↓H␈↓Note that the computations in ␈↓αdeval␈↓ are basically of two categories:
␈↓ ↓H␈↓␈↓ α_␈↓↓1.␈↓␈α∩Simple␈α∪transformations␈α∩like␈α∩sending,␈α∪building␈α∩␈↓αdest␈↓␈α∩blocks,␈α∪or␈α∩selecting␈α∪components␈α∩of
␈↓ ↓H␈↓␈↓ α_expressions.␈α→These␈α→computations␈α→are␈α→non-recursive,␈α→requiring␈α→a␈α→bounded␈α→amount␈α_of
␈↓ ↓H␈↓␈↓ α_computation.
␈↓ ↓H␈↓␈↓ α_␈↓↓2.␈↓␈αRecursive␈αcalls␈αon␈αthe␈αevaluator␈αor␈αits␈αsubfunctions.␈αThese␈αcomputations␈αcan␈αbe␈αarbitrarily
␈↓ ↓H␈↓␈↓ α_complex.
␈↓ ↓H␈↓It␈αis␈αthe␈α
recursive␈αcomputations␈αwhich␈αwe␈α
wish␈αto␈αexamine.␈αOne␈α
of␈αthe␈αimplications␈αof␈α
a␈αfunction
␈↓ ↓H␈↓call␈α⊂is␈α∂that␈α⊂we␈α∂have␈α⊂further␈α∂computation␈α⊂to␈α∂be␈α⊂performed␈α∂␈↓↓after␈↓␈α⊂the␈α∂call␈α⊂is␈α∂completed.␈α⊂It␈α⊂is␈α∂the
␈↓ ↓H␈↓responsibility␈α∞of␈α
the␈α∞evaluator␈α∞to␈α
remember␈α∞where␈α∞a␈α
computation␈α∞has␈α∞been␈α
interrupted␈α∞so␈α∞that␈α
it
␈↓ ↓H␈↓may␈α∃pick␈α∃up␈α∃where␈α∃it␈α∃left␈α∃off,␈α∃after␈α∃completing␈α∃the␈α∃call.␈α∃ One␈α∃of␈α∃the␈α∃major␈α∃problems␈α∃in
␈↓ ↓H␈↓implementing␈αevaluators␈αis␈α"how␈αto␈αremember".␈α If␈αthe␈αfunction␈αbeing␈αcalled␈αis␈αa␈αsimple␈αcalculation
␈↓ ↓H␈↓of␈αtype␈α␈↓↓1.␈↓␈αabove,␈αthen␈αwe␈αcould␈αreplace␈αthe␈αcall␈αwith␈αa␈αcopy␈αof␈αthe␈αbody␈αof␈αthe␈αdefinition␈αwhere␈αwe
␈↓ ↓H␈↓have␈α
replaced␈α
each␈α
occurrence␈α
of␈α
a␈α
formal␈α
parameter␈α
with␈α
the␈α
appropriate␈α
actual␈α∞parameter;␈α
this
␈↓ ↓H␈↓works␈α
nicely.␈α
Indeed␈α
making␈αsuch␈α
formal␈α
substitutions␈α
works␈α
for␈αcomputations␈α
of␈α
type␈α
␈↓↓2.␈↓␈α
as␈αwell.
␈↓ ↓H␈↓However the solution in this case is not sufficiently efficient.
␈↓ ↓H␈↓Previous␈α⊃evaluators␈α∩"remembered"␈α⊃what␈α∩was␈α⊃to␈α∩be␈α⊃done␈α⊃either␈α∩by␈α⊃using␈α∩recursion,␈α⊃as␈α∩in␈α⊃␈↓αeval␈↓
␈↓ ↓H␈↓(Section 3.5),␈α⊃or␈α⊃by␈α⊃explicit␈α⊃sequencing␈α⊃as␈α⊃in␈α⊃␈↓αdeval␈↓.␈α⊃ We␈α⊃now␈α⊃propose␈α⊃to␈α⊃explicitly␈α∩␈↓↓pass␈α⊃along␈↓
␈↓ ↓H␈↓information␈α⊂about␈α⊂what␈α⊃to␈α⊂do␈α⊂after␈α⊃the␈α⊂current␈α⊂computation␈α⊃is␈α⊂completed.␈α⊂This␈α⊃information␈α⊂is
␈↓ ↓H␈↓called the ␈↓↓continuation␈↓.
␈↓ ↓H␈↓The␈αfirst␈αevaluator␈αof␈αthis␈αsection␈αis␈α␈↓αceval␈↓␈↓π 134␈↓;␈αit␈αis␈αa␈αmodification␈αof␈α␈↓αdeval␈↓λ'␈↓␈αof␈αpage 189.␈αIt␈αtakes␈αa
␈↓ ↓H␈↓single␈αargument␈α␈↓αc␈↓␈α
which␈αis␈αa␈αcontinutation.␈α
The␈αcontinutation␈αis␈αpassed␈α
along␈αas␈αa␈α
data␈αstructure
␈↓ ↓H␈↓until␈α⊂␈↓αceval␈↓␈α∂has␈α⊂completed␈α⊂its␈α∂current␈α⊂computation.␈α∂At␈α⊂that␈α⊂time␈α∂␈↓αc␈↓␈α⊂is␈α∂executed.␈α⊂ For␈α⊂example␈α∂we
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 134␈↓ ␈↓αc␈↓ for ␈↓↓c␈↓ontrol or ␈↓↓c␈↓ontinuation
␈↓ ↓H␈↓␈↓↓4.7␈↓ λ~␈↓αeval␈↓↓ with Explicit Control 193␈↓α
␈↓ ↓H␈↓transform␈α
␈↓αdeval␈↓λ'␈↓␈αinto␈α
␈↓αceval␈↓␈α
by␈αforming␈α
a␈α
continuation␈αfrom␈α
that␈α
portion␈αof␈α
␈↓αdeval␈↓λ'␈↓␈α
which␈αfollows␈α
the
␈↓ ↓H␈↓call on ␈↓αdeval␈↓β1␈↓. Thus:
␈↓ ↓H␈↓αceval <= λ[[c]␈↓ β_[isconst[] → send[denote[]];c[];
␈↓ ↓H␈↓α␈↓ β_ isvar[] → send[lookup[]];c[];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α →␈↓ βXsave[fun;func[]];
␈↓ ↓H␈↓α␈↓ β_␈↓ βXsave[args;arglist[]];
␈↓ ↓H␈↓α␈↓ β_␈↓ βXceval␈↓β1␈↓α[function[ev1]] ]]
␈↓ ↓H␈↓αev1 <= λ[[ ] restore[args]; restore[func]; c[] ]]
␈↓ ↓H␈↓For␈α∂the␈α∂simple␈α∂cases␈α∂we␈α∂just␈α∂execute␈α∂the␈α∂continuation␈α∂after␈α∂the␈α∂␈↓αsend␈↓;␈α∂when␈α∂we␈α∂have␈α∂a␈α∞function
␈↓ ↓H␈↓application␈αwe␈α
make␈αup␈αa␈α
new␈αcontinuation.␈α When␈α
␈↓αceval␈↓β1␈↓␈αis␈αfinished␈α
with␈αthe␈αfunction␈α
application
␈↓ ↓H␈↓it executes ␈↓αev1␈↓; that does the ␈↓αrestore␈↓ operations and then performs the saved continuation.
␈↓ ↓H␈↓Note␈α∞the␈α
use␈α∞of␈α
␈↓αfunction␈↓.␈α∞The␈α
non-local␈α∞variable␈α
␈↓αc␈↓␈α∞in␈α
␈↓αev1␈↓␈α∞represents␈α
the␈α∞continuation␈α∞passed␈α
into
␈↓ ↓H␈↓␈↓αceval␈↓.␈αTherefore␈α␈↓αc␈↓␈αmust␈αbe␈αfound␈αin␈αthe␈αenvironment␈αof␈αthe␈αbody␈αof␈α␈↓αceval␈↓␈α␈↓↓not␈↓␈αin␈αthe␈αenvironment
␈↓ ↓H␈↓which is current when ␈↓αev1␈↓ is applied.
␈↓ ↓H␈↓As before, ␈↓αeval␈↓ is expressible with the new evaluator:
␈↓ ↓H␈↓α␈↓ β_eval <= λ[[x;y]␈↓ ∧xfun ← ();
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧xargs ← ();
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧xexp ← x;
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧xenv ← y;
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧xdest ← alloc_dest[(TLB)];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧xceval[function[λ[[ ] val[dest]]]] ]
␈↓ ↓H␈↓Transforming␈α∞the␈α∂sub-functions␈α∞of␈α∞␈↓αdeval␈↓λ'␈↓␈α∂is␈α∞reasonably␈α∞straightforward:␈α∂the␈α∞segment␈α∂of␈α∞program
␈↓ ↓H␈↓below␈α
a␈αcall␈α
on␈αone␈α
of␈αthe␈α
recursive␈α
parts␈αof␈α
the␈αevaluator␈α
is␈αnamed;␈α
a␈αnew␈α
continuation␈α
is␈αmade
␈↓ ↓H␈↓like␈αwe␈α
did␈αfor␈α␈↓αev1␈↓;␈α
the␈αtransformation␈αprocess␈α
is␈αapplied␈αto␈α
each␈αnew␈αcontinuation.␈α
For␈αexample,
␈↓ ↓H␈↓here's ␈↓αceval␈↓β1␈↓:
␈↓ ↓H␈↓αceval␈↓β1␈↓α <= λ[[c]␈↓ β_[isatom[] →␈↓ ∧H[iscond[] → devcond[c];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧H isprim[] →␈↓ ¬Xsave[env;env];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧H␈↓ ¬Xsave[dest;alloc_dest[createvars[]]];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧H␈↓ ¬Xevalargs[function[ev2]];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧H ␈↓
t␈↓α → ceval␈↓β2␈↓α[];
␈↓ ↓H␈↓α␈↓ β_islambda[] →␈↓ ∧Hsave[env;env];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧Hsave[dest;alloc_dest[vars[]]
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧Hevalargs[function[ev5]];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → ceval␈↓β2␈↓α[]] ]]
␈↓ ↓H␈↓␈↓αceval␈↓β2␈↓α <= λ[[ ] save[exp;fun]; ceval[function[ev3]]]␈↓
␈↓ ↓H␈↓αev2 <= λ[[ ] link[]; restore[dest]; execute[]; restore[env]; c[]]
␈↓ ↓H␈↓␈↓↓194 Imperative Constructs in LISP␈↓ 24.7␈↓
␈↓ ↓H␈↓αev3 <= λ[[ ] restore[exp]; save[fun;receive[]]; ceval␈↓β1␈↓α[function[ev4]]]
␈↓ ↓H␈↓αev4 <= λ[[ ] restore[fun]; c[]]
␈↓ ↓H␈↓αev5 <= λ[[ ] link[]; restore[dest]; save[args;bodylist[]]; evalargs[function[ev6]]]
␈↓ ↓H␈↓αev6 <= λ[[ ] restore[args]; restore[env]; c[]]
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I.␈α∂Continuations␈α∂can␈α∂also␈α∂be␈α∂used␈α∂as␈α∂general␈α∂programming␈α∂tools.␈α∂For␈α∂example,␈α∂evaluate␈α∂␈↓αfact␈↓β2␈↓α[2]␈↓
␈↓ ↓H␈↓where:
␈↓ ↓H␈↓␈↓αfact␈↓β2␈↓α <= λ[[x] fact␈↓β2␈↓λ'␈↓α[x;function[λ[[x] x]]]]
␈↓ ↓H␈↓αfact␈↓β2␈↓λ'␈↓α <= λ[[n;f]␈↓ β_[zerop[n] → f[1];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → fact␈↓β2␈↓λ'␈↓α[␈↓ ∧(sub1[n];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧(function[λ[[x] f[times[n;x]]]]]]]
␈↓ ↓H␈↓II. Write the new version of ␈↓αdevcond␈↓ and ␈↓αevalargs␈↓.
␈↓ ↓H␈↓III. Using the new evaluator, sketch the evaluation of ␈↓αf[A]␈↓ where: ␈↓αf <= λ[[x] eq[x;A]]␈↓.
␈↓ ↓H␈↓The␈α
final␈α
step␈αis␈α
analogous␈α
to␈αthat␈α
which␈α
we␈αperformed␈α
moving␈α
from␈α␈↓αdeval␈↓␈α
to␈α
␈↓αdeval␈↓λ'␈↓:␈α
we␈αremove
␈↓ ↓H␈↓the␈α
argument␈α
to␈α
␈↓αceval␈↓␈αand␈α
pass␈α
the␈α
continuation␈α
explicitly␈αin␈α
a␈α
non-local␈α
variable␈α
named␈α␈↓αcont␈↓.␈α
This
␈↓ ↓H␈↓new evaluator is named ␈↓αceval␈↓λ'␈↓:
␈↓ ↓H␈↓αceval␈↓λ'␈↓α <= λ[[ ]␈↓ β_[isconst[] → send[denote[]]; cont[];
␈↓ ↓H␈↓α␈↓ β_ isvar[] → send[lookup[]]; cont[];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α →␈↓ βXsave[fun;func[]];
␈↓ ↓H␈↓α␈↓ β_␈↓ βXsave[args;arglist[]];
␈↓ ↓H␈↓α␈↓ β_␈↓ βXsave[cont;function[ev1]];
␈↓ ↓H␈↓α␈↓ β_␈↓ βXceval␈↓β1␈↓α[] ]]
␈↓ ↓H␈↓αev1 <= λ[[ ] restore[args]; restore[func]; restore[cont]; cont[] ]]
␈↓ ↓H␈↓We␈α↔can␈α↔remove␈α↔more␈α↔control␈α↔structure␈α_from␈α↔the␈α↔evaluator␈α↔by␈α↔noting␈α↔that␈α_executing␈α↔the
␈↓ ↓H␈↓continuation,␈α∩"␈↓αcont[]␈↓",␈α∩and␈α∩executing␈α∩the␈α∩explicit␈α⊃calls␈α∩on␈α∩the␈α∩evaluator's␈α∩subfunctions␈α∩are␈α⊃two
␈↓ ↓H␈↓manifestations␈α
of␈α
the␈αsame␈α
phenomenon.␈α
In␈αthe␈α
first␈α
case␈αwe␈α
restore␈α
to␈αa␈α
variable␈α
and␈αthen␈α
execute
␈↓ ↓H␈↓the␈α
variable␈αas␈α
a␈α
function␈αapplication;␈α
in␈α
the␈αsecond,␈α
we␈α
execute␈αa␈α
known␈α
call.␈αWe␈α
can␈αreplace␈α
these
␈↓ ↓H␈↓␈↓↓4.7␈↓ λ~␈↓αeval␈↓↓ with Explicit Control 195␈↓α
␈↓ ↓H␈↓two␈αactions␈αby␈αa␈αcommon␈αaction␈αif␈αwe␈αalways␈αexecute␈αfrom␈αthe␈αvariable␈α␈↓αcont␈↓␈αand␈αreplace␈αcalls␈αlike
␈↓ ↓H␈↓"␈↓αceval␈↓β1␈↓α[]␈↓" with the sequence:
␈↓ ↓H␈↓α␈↓ ∧ysave[cont;function[ceval␈↓β1␈↓α]]; cont[];
␈↓ ↓H␈↓Notice␈αthat␈αwhen␈αwe␈αmake␈αthis␈αlast␈α␈↓αsave␈↓␈αwe␈αknow␈αthat␈αthe␈αcurrent␈αvalue␈αof␈α␈↓αcont␈↓␈αis␈α␈↓αev1␈↓.␈αNotice␈αalso
␈↓ ↓H␈↓that␈αwhen␈αwe␈αexecute␈α␈↓αcont[]␈↓␈αwe␈αenter␈α␈↓αceval␈↓β1␈↓␈αand␈αtherefore␈αwithin␈αthis␈αcall␈αon␈α␈↓αceval␈↓β1␈↓,␈α␈↓αcont␈↓␈α␈↓↓is␈↓␈α␈↓αceval␈↓β1␈↓.
␈↓ ↓H␈↓All␈αthis␈αdiscussion␈αcan␈αbe␈αsimplified␈αif␈αwe␈α
think␈αa␈αbit␈αabout␈αthe␈αpurpose␈αof␈αcontinuations:␈α
we␈αwill
␈↓ ↓H␈↓need␈α
to␈α
make␈α
note␈α
of␈α
what␈α
the␈α∞continuation␈α
should␈α
be␈α
␈↓↓after␈↓␈α
the␈α
current␈α
computation␈α∞is␈α
finished;
␈↓ ↓H␈↓and␈α
we␈αwill␈α
need␈αto␈α
set␈α
␈↓αcont␈↓␈αto␈α
designate␈αwhat␈α
computation␈α
to␈αdo␈α
now.␈α We␈α
therefore␈α
introduce␈αa
␈↓ ↓H␈↓binary␈αprimitive␈α␈↓αsave_cont␈↓␈αwhich␈αwill␈αsave␈αits␈αfirst␈αargument␈αsuch␈αthat␈α␈↓αrestore␈↓␈αcan␈αrestore␈αit␈αto␈α␈↓αcont␈↓
␈↓ ↓H␈↓at the appropriate time; ␈↓αsave_cont␈↓ will set ␈↓αcont␈↓ from its second argument.
␈↓ ↓H␈↓α␈↓ ∧@save_cont <= λ[[x;y] cont ← x; save[cont;y]]
␈↓ ↓H␈↓We can remove the calls ␈↓αcont[]␈↓, and perform the execution outside ␈↓αceval␈↓λ'␈↓ using a simple loop:
␈↓ ↓H␈↓α␈↓ ¬Xloop <= λ[[] prog[[]
␈↓ ↓H␈↓α␈↓ ¬X␈↓ εXl␈↓ εxcont[]
␈↓ ↓H␈↓α␈↓ ¬X␈↓ εX␈↓ εxgo[l] ]]
␈↓ ↓H␈↓Each␈α
function␈αexecuted␈α
by␈α␈↓αcont[]␈↓␈α
will␈α
perform␈αsome␈α
simple␈αoperations␈α
like␈α␈↓αsend␈↓␈α
or␈α
␈↓αalloc_dest␈↓,␈αand
␈↓ ↓H␈↓then␈α
will␈α
exit,␈α
setting␈α␈↓αcont␈↓␈α
to␈α
a␈α
function␈αname.␈α
The␈α
next␈α
pass␈α
around,␈α␈↓αloop␈↓␈α
will␈α
execute␈α
the␈αnew␈α
␈↓αcont␈↓.
␈↓ ↓H␈↓After slight reorganization to eliminate some ␈↓αsave-restore␈↓ operations on ␈↓αcont␈↓, we have:
␈↓ ↓H␈↓αceval␈↓λ''␈↓α <= λ[[ ]␈↓ β_[isconst[] → send[denote[]]; restore[cont];
␈↓ ↓H␈↓α␈↓ β_ isvar[] → send[lookup[]]; restore[cont];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α →␈↓ βXsave[fun;func[]];
␈↓ ↓H␈↓α␈↓ β_␈↓ βXsave[args;arglist[]];
␈↓ ↓H␈↓α␈↓ β_␈↓ βXsave_cont[quote[ev1];quote[ceval␈↓β1␈↓α]] ]]
␈↓ ↓H␈↓αev1 <= λ[[ ] restore[args]; restore[func]; restore[cont] ]]
␈↓ ↓H␈↓Notice␈αthe␈αuse␈αof␈α␈↓αquote␈↓␈αrather␈αthan␈α␈↓αfunction␈↓.␈αIn␈αthe␈αprevious␈αevaluators␈αwe␈αused␈α␈↓αfunction␈↓␈αsince␈αwe
␈↓ ↓H␈↓had␈αto␈αsave␈αthe␈αcurrent␈αenvironment;␈αbut␈αthe␈αcontinuation␈α␈↓αc␈↓␈αwas␈αthe␈αonly␈αfree␈αvariable␈αwhich␈αwas
␈↓ ↓H␈↓in␈α∞jeopardy.␈α
In␈α∞␈↓αceval␈↓λ''␈↓␈α
we␈α∞have␈α
explicitly␈α∞saved␈α
the␈α∞continuation␈α
using␈α∞␈↓αsave_cont␈↓,␈α
and␈α∞thus␈α
␈↓αquote␈↓
␈↓ ↓H␈↓plus␈αthe␈αproper␈αuse␈αof␈α␈↓αrestore␈↓␈αcan␈αreplace␈α␈↓αfunction␈↓.␈αWe␈αwill␈αalso␈αintroduce␈αan␈αabbreviation,␈αwriting
␈↓ ↓H␈↓␈↓λ`␈↓αxx␈↓ for ␈↓αquote[xx]␈↓␈↓π 135␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 135␈↓ This abbreviation is used in several implementations of LISP. See page 260.
␈↓ ↓H␈↓␈↓↓196 Imperative Constructs in LISP␈↓ 24.7␈↓
␈↓ ↓H␈↓α␈↓Finally, here's ␈↓αeval␈↓:
␈↓ ↓H␈↓α␈↓ β(eval <= λ[[x;y] catch[␈↓ ¬8prog[[ ]␈↓ ε(fun ← ();
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬8␈↓ ε(args ← ();
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬8␈↓ ε(exp ← x;
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬8␈↓ ε(env ← y;
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬8␈↓ ε(dest ← alloc_dest[(TLB)];
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬8␈↓ ε(save_cont[␈↓λ`␈↓αλ[[]throw[val[dest]; out]]]; ␈↓λ`␈↓αceval␈↓λ''␈↓α];
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬8␈↓ ε(loop[]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬8out]]
␈↓ ↓H␈↓What␈α∀has␈α∀been␈α∀gained␈α∃by␈α∀these␈α∀transformations␈α∀of␈α∀the␈α∃original␈α∀␈↓αeval␈↓?␈α∀ We␈α∀have␈α∃made␈α∀the
␈↓ ↓H␈↓mechanisms␈αwhich␈αwere␈αimplicit␈αin␈αLISP␈αvery␈αexplicit.␈α We␈αhave␈αdescribed␈αthe␈αimplementations␈αof
␈↓ ↓H␈↓LISP's␈α∩access␈α∩and␈α∪control␈α∩requirements␈α∩in␈α∪terms␈α∩of␈α∩very␈α∪simple␈α∩computations.␈α∩We␈α∪now␈α∩have
␈↓ ↓H␈↓developed␈α∂enough␈α∂detail␈α∂that␈α⊂we␈α∂can␈α∂give␈α∂a␈α∂faithful␈α⊂implementation␈α∂description␈α∂of␈α∂all␈α⊂of␈α∂LISP
␈↓ ↓H␈↓including the ␈↓αfunction␈↓ and ␈↓αprog␈↓ constructs.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Could we use statements like ␈↓αsave_cont[ev1;eval␈↓β1␈↓α]␈↓ rather than ␈↓αsave_cont[␈↓λ`␈↓αev1; ␈↓λ`␈↓αeval␈↓β1␈↓α]␈↓?
␈↓ ↓H␈↓II. Using the new evaluator, sketch the evaluation of ␈↓αf[A]␈↓ where: ␈↓αf <= λ[[x] eq[x;A]]␈↓.
␈↓ ↓H␈↓␈↓ ¬≡␈↓↓4.8 An Evaluator for ␈↓αprog␈↓␈↓α
␈↓ ↓H␈↓The␈αevaluator␈αin␈αthis␈αsection␈αwill␈αbe␈αthe␈αdefinitive␈αinterpreter␈αfor␈αLISP␈αthroughout␈αthe␈αrest␈αof␈αthis
␈↓ ↓H␈↓book. It will handle the applicative subset of LISP as well as handling ␈↓αprog␈↓ related constructs.
␈↓ ↓H␈↓We␈α∩need␈α∪to␈α∩add␈α∪more␈α∩mechanism␈α∩to␈α∪handle␈α∩␈↓αprog␈↓.␈α∪For␈α∩example␈α∩the␈α∪execution␈α∩of␈α∪the␈α∩␈↓αreturn␈↓
␈↓ ↓H␈↓statement␈αrequires␈αthat␈αwe␈αlocate␈αdynamically␈αsurrounding␈α␈↓αprog␈↓s.␈αThe␈α␈↓αgo␈↓␈αmust␈αalso␈αlocate␈αthe␈αlatest
␈↓ ↓H␈↓␈↓αprog␈↓␈α
which␈α
surrounds␈α
the␈α
␈↓αgo␈↓␈αand␈α
contains␈α
the␈α
desired␈α
label.␈α The␈α
evaluator␈α
needs␈α
to␈α
know␈αwhen
␈↓ ↓H␈↓we␈αare␈αevaluating␈αa␈αconditional␈αexpression␈αand␈αwhen␈αwe␈αare␈αevaluating␈αa␈αconditional␈αstatement;␈αif
␈↓ ↓H␈↓we␈α∪are␈α∩(immediately)␈α∪in␈α∩a␈α∪␈↓αprog␈↓␈α∪then␈α∩it's␈α∪a␈α∩conditional␈α∪statement,␈α∩otherwise␈α∪it's␈α∪a␈α∩conditional
␈↓ ↓H␈↓expression.␈α∩ All␈α⊃of␈α∩this␈α∩information␈α⊃could␈α∩be␈α⊃discovered␈α∩by␈α∩the␈α⊃evaluator␈α∩using␈α∩the␈α⊃currently
␈↓ ↓H␈↓supplied␈α∂information,␈α∂however␈α∂the␈α∂evaluator␈α∂can␈α⊂be␈α∂made␈α∂more␈α∂efficient␈α∂by␈α∂adding␈α∂a␈α⊂bit␈α∂more
␈↓ ↓H␈↓explicit␈αinformation.␈αMost␈αof␈αthe␈αadditions␈αinvolve␈α␈↓αprog␈↓-entry,␈α␈↓αgo␈↓,␈αand␈α␈↓αreturn␈↓␈αand␈αwill␈αtherefore␈αbe
␈↓ ↓H␈↓presented␈αwhen␈αwe␈αdiscuss␈αthat␈αpart␈αof␈αthe␈αevaluator.␈αThe␈αonly␈αaddition␈αwe␈αwill␈αmake␈αnow␈αwill␈αbe
␈↓ ↓H␈↓introduction␈α∪of␈α∪a␈α∪variable␈α∩␈↓αtype␈↓␈α∪which␈α∪is␈α∪set␈α∩to␈α∪␈↓αPROC␈↓␈α∪when␈α∪we␈α∩begin␈α∪an␈α∪evaluation␈α∪of␈α∩an
␈↓ ↓H␈↓application, and is set to ␈↓αPROG␈↓ when we enter a ␈↓αprog␈↓.
␈↓ ↓H␈↓␈↓↓4.8␈↓ λPAn Evaluator for ␈↓αprog␈↓ 197␈↓α
␈↓ ↓H␈↓We␈αwill␈αalso␈αrework␈αsome␈αof␈αour␈αcurrent␈αsub-functions␈αto␈αimprove␈αreadability.␈α Since␈αsequences␈αof
␈↓ ↓H␈↓␈↓αsave␈↓s␈α
happen␈α
frequently␈α
in␈α
the␈α
evaluators␈α
we␈α
introduce␈α
a␈α
new␈α
procedure␈α
named␈α
␈↓αsave␈↓λ'␈↓␈α
which␈α
acts
␈↓ ↓H␈↓like␈α⊃a␈α⊃sequence␈α⊃of␈α⊃calls␈α⊃on␈α⊃␈↓αsave␈↓␈α⊃for␈α⊃arguments␈α⊃other␈α⊃than␈α⊃␈↓αcont␈↓.␈α⊃ In␈α⊃this␈α⊃latter␈α⊃case,␈α⊃a␈α⊃call␈α⊃on
␈↓ ↓H␈↓␈↓αsave_cont␈↓ is simulated. Similarly we introduce an iterated version of ␈↓αrestore␈↓ named ␈↓αrestore␈↓λ'␈↓.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓Write ␈↓αrestore␈↓λ'␈↓ and ␈↓αsave␈↓λ'␈↓ as macros which expand to calls on ␈↓αsave␈↓ and ␈↓αrestore␈↓.
␈↓ ↓H␈↓αpeval <= λ[[ ]␈↓ β_[isconst[] → send[denote[]];restore[cont];
␈↓ ↓H␈↓α␈↓ β_ isvar[] → send[lookup[]];restore[cont];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α →␈↓ βhsave␈↓λ'␈↓α[␈↓ ∧8fun;func[];
␈↓ ↓H␈↓α␈↓ β_␈↓ βh␈↓ ∧8args;arglist[];
␈↓ ↓H␈↓α␈↓ β_␈↓ βh␈↓ ∧8cont; ␈↓λ`␈↓αev1; ␈↓λ`␈↓αpeval␈↓β1␈↓α] ]]
␈↓ ↓H␈↓αev1 <= λ[[ ] restore␈↓λ'␈↓α[args;func;cont] ]]
␈↓ ↓H␈↓The␈α
responsibility␈α
of␈α
␈↓αpeval␈↓␈αis␈α
to␈α
recognize␈α
the␈αoccurrence␈α
of␈α
one␈α
of␈αthe␈α
basic␈α
forms:␈α
a␈α
variable,␈αa
␈↓ ↓H␈↓constant,␈α
or␈α
a␈α
function␈αapplication.␈α
Discovering␈α
the␈α
structure␈α
of␈αan␈α
application␈α
is␈α
the␈α
business␈αof
␈↓ ↓H␈↓␈↓αpeval␈↓β1␈↓.␈α∞ We␈α∞need␈α∞to␈α∞know␈α∞whether␈α∞the␈α∞function␈α∞position␈α∞represents␈α∞a␈α∞call-by-value␈α∞function␈α∞or␈α
a
␈↓ ↓H␈↓special␈αform.␈αSo␈αfar␈αthe␈αonly␈αspecial␈αform␈αwe␈αrecognize␈αis␈α␈↓αcond␈↓␈↓π 136␈↓;␈αhowever␈αmany␈αof␈αthe␈αconstructs
␈↓ ↓H␈↓which␈α⊂␈↓αprog␈↓␈α⊂introduced␈α⊂are␈α⊂special␈α⊂forms.␈α⊃We␈α⊂could␈α⊂add␈α⊂a␈α⊂collection␈α⊂of␈α⊂recognizers␈α⊃␈↓αissetq␈↓,␈α⊂␈↓αisgo␈↓,
␈↓ ↓H␈↓␈↓αisprog␈↓,␈αetc.,␈αto␈αaugment␈αthe␈αexisting␈α␈↓αiscond␈↓.␈αInstead␈αwe␈αwould␈αrather␈αadd␈αa␈αdevice␈αsimilar␈αto␈α␈↓αisprim␈↓
␈↓ ↓H␈↓but␈α⊂instead␈α⊂of␈α⊂handling␈α⊂the␈α⊂call-by-value␈α⊂primitives␈α⊂with␈α⊂the␈α⊂underlying␈α⊂evaluator,␈α⊂we␈α⊂wish␈α⊂to
␈↓ ↓H␈↓handle␈αspecial␈αforms␈αwith␈αour␈αown␈αpieces␈αof␈α␈↓αpeval␈↓.␈αWe␈αneed␈αa␈αpredicate␈αnamed␈α␈↓αisspec␈↓␈αto␈αrecognize
␈↓ ↓H␈↓occurrences␈α∂of␈α∞special␈α∂forms␈α∂and␈α∞will␈α∂need␈α∞to␈α∂add␈α∂functions␈α∞to␈α∂␈↓αpeval␈↓␈α∞to␈α∂execute␈α∂the␈α∞appropriate
␈↓ ↓H␈↓programs␈α∂when␈α∞␈↓αisspec␈↓␈α∂is␈α∂true.␈α∞We␈α∂will␈α∂do␈α∞this␈α∂by␈α∞introducing␈α∂a␈α∂global␈α∞table␈α∂called␈α∂␈↓αspectbl␈↓.␈α∞The
␈↓ ↓H␈↓name␈αcomponents␈αof␈αthe␈αtable␈αwill␈αbe␈αthe␈αnames␈αfor␈αspecial␈αforms;␈αthe␈αvalue␈αcomponents␈αof␈α␈↓αspectbl␈↓
␈↓ ↓H␈↓will␈α
be␈α∞the␈α
names␈α∞of␈α
functions␈α∞which␈α
will␈α
evaluate␈α∞the␈α
corresponding␈α∞special␈α
form␈↓π 137␈↓.␈α∞ Then␈α
we
␈↓ ↓H␈↓can write:
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 136␈↓␈α∞Actually␈α
␈↓αquote␈↓␈α∞is␈α∞also␈α
a␈α∞special␈α
form␈α∞which␈α∞we␈α
recognize,␈α∞however␈α
its␈α∞recognition␈α∞is␈α
handled
␈↓ ↓H␈↓within ␈↓αisconst␈↓.
␈↓ ↓H␈↓␈↓π 137␈↓ In the next chapter we will see a more efficient way to recognize and execute special forms.
␈↓ ↓H␈↓␈↓↓198 Imperative Constructs in LISP␈↓ 14.8␈↓
␈↓ ↓H␈↓α␈↓ β(isspec <= λ[[ ][null[nassoc[fun;spectbl]] → ␈↓
f␈↓α; ␈↓
t␈↓α → ␈↓
t␈↓α]
␈↓ ↓H␈↓α␈↓ β(nassoc <= λ[[x;l]␈↓ ¬λ[null[l] → ( );
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬λ eq[x;name[first[l]]] → first[l];
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬λ ␈↓
t␈↓α → nassoc[x;rest[l]]]
␈↓ ↓H␈↓To␈α
execute␈α
the␈α
appropriate␈α
routine␈α
we␈α
need␈α
only␈α
put␈α
the␈α
name␈α
in␈α
the␈α
variable␈α
␈↓αcont␈↓␈α
and␈α
␈↓αloop␈↓␈αwill␈α
do
␈↓ ↓H␈↓the rest. We can load ␈↓αcont␈↓ by:
␈↓ ↓H␈↓α␈↓ β∀cont ← valspec[ ]; ␈↓where: ␈↓αvalspec <= λ[[ ]value[nassoc[fun;spectbl]]]
␈↓ ↓H␈↓For␈α
example,␈αwith␈α
␈↓αspectbl␈↓␈α
bound␈αto␈α
␈↓α((COND␈αDEVCOND))␈↓,␈α
our␈α
previous␈α␈↓αceval␈↓β1␈↓␈α
would␈α
work␈αquite
␈↓ ↓H␈↓nicely as:
␈↓ ↓H␈↓αceval␈↓β1␈↓α <= λ[[ ]␈↓ β_[isatom[] →␈↓ ∧([isspec[] → cont ← valspec[ ];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧( isprim[] →␈↓ ¬hsave[env;env];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧( ... ] ... ]]
␈↓ ↓H␈↓Before␈αintroducing␈α␈↓αpeval␈↓β1␈↓␈αwe␈αshould␈αsay␈αa␈αbit␈αabout␈αthe␈αinefficiency␈αinvolved␈αin␈αthe␈α␈↓αisspec␈↓-␈↓αvalspec␈↓
␈↓ ↓H␈↓pair.␈α∀We␈α∃already␈α∀noted␈α∀that␈α∃the␈α∀linear␈α∃search␈α∀encoded␈α∀in␈α∃␈↓αassoc␈↓␈α∀is␈α∃unnecessarily␈α∀inefficient.
␈↓ ↓H␈↓However␈α∞the␈α∂present␈α∞predicate-function␈α∂pair␈α∞is␈α∂even␈α∞more␈α∞wasteful;␈α∂if␈α∞␈↓αisspec␈↓␈α∂␈↓↓is␈↓␈α∞true␈α∂we␈α∞perform
␈↓ ↓H␈↓␈↓αnassoc[fun;spectbl]␈↓␈α∞twice.␈α∞ A␈α∞more␈α
efficient␈α∞computation␈α∞might␈α∞save␈α∞the␈α
result␈α∞of␈α∞the␈α∞first␈α∞call␈α
on
␈↓ ↓H␈↓␈↓αnassoc␈↓ in a temporary variable ␈↓αt1␈↓ and if ␈↓αisspec␈↓ is true, move the ␈↓αvalue␈↓-part of ␈↓αt1␈↓ to ␈↓αcont␈↓. Thus:
␈↓ ↓H␈↓α␈↓ β(isspec <= λ[[ ]␈↓ ∧xt1 ← nassoc[fun;spectbl]]
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧x[null[t1] → ␈↓
f␈↓α; ␈↓
t␈↓α → ␈↓
t␈↓α] ]
␈↓ ↓H␈↓α␈↓with:␈↓ β(␈↓αvalspec <= λ[[ ] value[t1]]
␈↓ ↓H␈↓This␈αis␈α
a␈αuseful␈αprogramming␈α
trick␈αbut␈αdoes␈α
not␈αadd␈αto␈α
the␈αclarity␈αof␈α
the␈αprogram.␈α
In␈αSection 5.5
␈↓ ↓H␈↓we shall see a more subtle, but related trick.
␈↓ ↓H␈↓What␈αfollows␈αis␈αthe␈αremainder␈αof␈αthe␈αevaluator␈αinterspersed␈αwith␈αcommentary.␈α The␈αmain␈αfunction
␈↓ ↓H␈↓is␈α␈↓αpeval␈↓β1␈↓;␈αit␈αhandles␈αfunction␈αapplications.␈α The␈αapplication␈αis␈αeither␈αa␈αcall-by-value␈α
application␈αor
␈↓ ↓H␈↓it␈α∂is␈α∂a␈α∂special␈α∂form.␈α⊂An␈α∂instance␈α∂of␈α∂the␈α∂first␈α∂requires␈α⊂evaluation␈α∂of␈α∂the␈α∂argument␈α∂list␈α⊂and␈α∂then
␈↓ ↓H␈↓evaluation␈α⊃of␈α⊃the␈α∩procedure␈α⊃body.␈α⊃If␈α⊃the␈α∩application␈α⊃is␈α⊃a␈α⊃special␈α∩form␈α⊃then␈α⊃the␈α∩evaluation␈α⊃is
␈↓ ↓H␈↓handled␈α↔by␈α⊗a␈α↔special␈α⊗piece␈α↔of␈α⊗the␈α↔evaluator,␈α⊗using␈α↔the␈α⊗mechanism␈α↔described␈α↔above.␈α⊗The
␈↓ ↓H␈↓call-by-value␈αapplications␈αare␈αeither␈αprimitive␈αapplications␈αor␈αare␈αanonymous␈αfunction␈αapplications.
␈↓ ↓H␈↓If␈α∞the␈α∞form␈α∞is␈α∞not␈α∞recognizable␈α∞then␈α∂the␈α∞function-position␈α∞is␈α∞evaluated␈α∞until␈α∞a␈α∞function␈α∂object␈α∞␈↓↓is␈↓
␈↓ ↓H␈↓recognized. At that time, the function is applied to its argument list.
␈↓ ↓H␈↓␈↓↓4.8␈↓ λPAn Evaluator for ␈↓αprog␈↓ 199␈↓α
␈↓ ↓H␈↓The␈αanomalous␈αsituation␈αinvolves␈αthe␈αapplication␈αof␈αa␈α␈↓αfunarg␈↓;␈αthough␈αit␈αis␈αpossible␈αto␈αhandle␈αthis
␈↓ ↓H␈↓case as a primitive, it is more instructive to present it in detail. Here is ␈↓αpeval␈↓β1␈↓:
␈↓ ↓H␈↓␈↓αpeval␈↓β1␈↓α <= λ[[ ]␈↓ βλ[isatom[] →␈↓ ∧8[isspec[] → cont ← valspec[ ];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8 isprim[] →␈↓ ¬Hsave␈↓λ'␈↓α[␈↓ ε_env;env;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬H␈↓ ε_dest;alloc_dest[createvars[]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬H␈↓ ε_cont; ␈↓λ`␈↓αev2; ␈↓λ`␈↓αevalargs];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8 ␈↓
t␈↓α → save␈↓λ'␈↓α[exp;fun;cont; ␈↓λ`␈↓αev3; ␈↓λ`␈↓αpeval];
␈↓ ↓H␈↓α␈↓ βλislambda[] →␈↓ ∧8save␈↓λ'␈↓α[␈↓ ¬λenv;env;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λdest;alloc_dest[vars[];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λcont; ␈↓λ`␈↓αev5; ␈↓λ`␈↓αevalargs];
␈↓ ↓H␈↓α␈↓ βλisfunarg[] →␈↓ ∧8prog[[x;y]␈↓ ¬Hx ← args;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬Hargs ← bodylist[second[fun]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬Hy ← env;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬Henv ← third[fun];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬Hsave␈↓λ'␈↓α[␈↓ ε_env;env;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬H␈↓ ε_args;x;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬H␈↓ ε_dest;alloc_dest[vars[second[fun]]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬H␈↓ ε_env;y;
␈↓ ↓H␈↓α␈↓ βλ␈↓ ∧8␈↓ ¬λ␈↓ ¬H␈↓ ε_cont; ␈↓λ`␈↓αev7; ␈↓λ`␈↓αevalargs]];
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α → save␈↓λ'␈↓α[exp;fun; cont; ␈↓λ`␈↓αev3; ␈↓λ`␈↓αpeval] ]]
␈↓ ↓H␈↓The functions ␈↓αev2␈↓ through ␈↓αev8␈↓ handle the control in ␈↓αpeval␈↓β1␈↓:
␈↓ ↓H␈↓α␈↓ βLev2 <= λ[[ ] link[]; restore[dest]; execute[]; restore␈↓λ'␈↓α[env;cont]]
␈↓ ↓H␈↓α␈↓This function passes the evaluation to the body of the primitive.
␈↓ ↓H␈↓␈↓ β7␈↓αev3 <= λ[[ ] restore[exp]; save␈↓λ'␈↓α[fun;receive[];cont; ␈↓λ`␈↓αev4; ␈↓λ`␈↓αpeval␈↓β1␈↓α]]
␈↓ ↓H␈↓␈↓αev3␈↓␈α
is␈α
the␈α
return␈α
point␈α∞when␈α
we␈α
have␈α
to␈α
evaluate␈α
the␈α∞function␈α
position␈α
of␈α
a␈α
form.␈α
When␈α∞␈↓αev3␈↓␈α
is
␈↓ ↓H␈↓called␈αthe␈α
result␈αof␈α
that␈αevaluation␈α
is␈αin␈αthe␈α
current␈αdest-slot.␈α
A␈α␈↓αreceive␈↓␈α
gets␈αthe␈α
value;␈αwe␈αthen␈α
pass
␈↓ ↓H␈↓the new form back to ␈↓αpeval␈↓β1␈↓.
␈↓ ↓H␈↓α␈↓ ¬∞ev4 <= λ[[ ] restore␈↓λ'␈↓α[fun;cont]]
␈↓ ↓H␈↓α␈↓ αlev5 <= λ[[ ] link[]; restore[dest]; save␈↓λ'␈↓α[args;bodylist[]; cont; ␈↓λ`␈↓αev6; ␈↓λ`␈↓αevalargs]]
␈↓ ↓H␈↓␈↓αev5␈↓␈α∞handles␈α
the␈α∞evaluation␈α∞of␈α
the␈α∞body␈α∞of␈α
a␈α∞λ-expression.␈α∞Since␈α
we␈α∞are␈α∞allowing␈α
multiple-bodied
␈↓ ↓H␈↓λ-expressions␈α∪(page 182),␈α∪we␈α∪pass␈α∪the␈α∪␈↓αbodylist␈↓␈α∪to␈α∪␈↓αevalargs␈↓.␈α∪If␈α∪we␈α∪were␈α∪restricting␈α∪ourselves␈α∩to
␈↓ ↓H␈↓single-bodied expressions, then passing ␈↓αbody␈↓ to ␈↓αpeval␈↓ would suffice.
␈↓ ↓H␈↓α␈↓ ∧nev6 <= λ[[ ] restore␈↓λ'␈↓α[args;env;cont]]
␈↓ ↓H␈↓␈↓↓200 Imperative Constructs in LISP␈↓ 14.8␈↓
␈↓ ↓H␈↓The␈α∞next␈α∞four␈α∞functions␈α∂handle␈α∞the␈α∞evaluation␈α∞of␈α∞a␈α∂sequence␈α∞of␈α∞expressions.␈α∞ If␈α∞the␈α∂sequence␈α∞is
␈↓ ↓H␈↓empty,␈α
then␈α
there␈α
is␈α
nothing␈α
to␈α
do.␈α
If␈α∞there␈α
is␈α
a␈α
single␈α
argument␈α
then␈α
evaluate␈α
it␈α
and␈α∞restore␈α
the
␈↓ ↓H␈↓continuation.␈α⊂Otherwise␈α⊂evaluate␈α∂the␈α⊂first␈α⊂one␈α⊂using␈α∂␈↓αpeval␈↓␈α⊂(sending␈α⊂its␈α∂result␈α⊂to␈α⊂␈↓αdest␈↓)␈α⊂and␈α∂then
␈↓ ↓H␈↓execute␈α
␈↓αev11␈↓.␈α At␈α
␈↓αev11␈↓␈αwe␈α
update␈αthe␈α
destination␈αblock␈α
using␈α␈↓αnext␈↓␈α
and␈αget␈α
set␈αto␈α
evaluate␈α
the␈αnext
␈↓ ↓H␈↓argument.
␈↓ ↓H␈↓αevalargs <= λ[[]␈↓ β([emptyargs[] → restore[cont];
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α →␈↓ βxsave[exp;first[args]];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxcont ← ␈↓λ`␈↓αev9 ]]
␈↓ ↓H␈↓αev9 <= λ[[ ]␈↓ αh[singlearg[] →␈↓ ∧(save_cont[ ␈↓λ`␈↓αev10; ␈↓λ`␈↓αpeval];
␈↓ ↓H␈↓α␈↓ αh ␈↓
t␈↓α →␈↓ β8save_cont[ ␈↓λ`␈↓αev11; ␈↓λ`␈↓αpeval] ]]
␈↓ ↓H␈↓αev10 <= λ[[ ] restore␈↓λ'␈↓α[exp;cont]]
␈↓ ↓H␈↓αev11 <= λ[[ ]␈↓ αh next[];
␈↓ ↓H␈↓α␈↓ αh args ← rest[args];
␈↓ ↓H␈↓α␈↓ αh exp ← first[args];
␈↓ ↓H␈↓α␈↓ αh cont ← ␈↓λ`␈↓αev9 ] ]
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓␈↓ αCUsing the new evaluator, sketch the evaluation of ␈↓αf[A]␈↓ where: ␈↓αf <= λ[[x] eq[x;A]]␈↓.
␈↓ ↓H␈↓The␈α∩combination␈α∩of␈α∩␈↓αevcond␈↓␈α∩and␈α∪␈↓αcond1␈↓␈α∩handle␈α∩conditional␈α∩expressions␈↓π 138␈↓.␈α∩ ␈↓αevcond␈↓␈α∩sets␈α∪up␈α∩the
␈↓ ↓H␈↓evaluation␈α
of␈α
the␈α
predicate␈α∞position␈α
such␈α
that␈α
the␈α
computation␈α∞will␈α
continue␈α
at␈α
␈↓αcond1␈↓.␈α∞When␈α
that
␈↓ ↓H␈↓evaluation␈α
is␈α
completed␈α
␈↓αcond1␈↓␈α
␈↓αreceive␈↓s␈α
the␈α
result.␈α
If␈α
␈↓
t␈↓␈α
is␈α
received␈α
then␈α
the␈α
consequent␈α
part␈α∞of␈α
that
␈↓ ↓H␈↓conditional␈α
clause␈αis␈α
evaluated.␈αNote␈α
that␈αwe␈α
use␈α
␈↓αevalargs␈↓␈αhere␈α
since␈αwe␈α
allow␈αextended␈α
conditionals
␈↓ ↓H␈↓(page 180). If ␈↓
f␈↓ is received we go back to ␈↓αevcond␈↓ with the remaining part of the conditional.
␈↓ ↓H␈↓αevcond <= λ[[ ]␈↓ βλ[emptyargs[] →␈↓ ∧Herr[NO_TRUE_COND_CLAUSE];
␈↓ ↓H␈↓α␈↓ βλ␈↓ βX␈↓ ∧Hcont ← ␈↓λ`␈↓αev1;
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α →␈↓ βXsave_cont[ ␈↓λ`␈↓αcond1; ␈↓λ`␈↓αpeval];
␈↓ ↓H␈↓α␈↓ βλ␈↓ βXexp ← pred[first[args]] ]]
␈↓ ↓H␈↓αcond1 <= λ[[ ]␈↓ αx[receive[] →␈↓ ∧(args ← conseq[first[args]];
␈↓ ↓H␈↓α␈↓ αx␈↓ βH␈↓ ∧(save_cont[ ␈↓λ`␈↓αev1; ␈↓λ`␈↓αevalargs];
␈↓ ↓H␈↓α␈↓ αx ␈↓
t␈↓α →␈↓ βHargs ← rest[args];
␈↓ ↓H␈↓α␈↓ αx␈↓ βHcont ← ␈↓λ`␈↓αevcond ]]
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 138␈↓ See the problem on page 205.
␈↓ ↓H␈↓␈↓↓4.8␈↓ λPAn Evaluator for ␈↓αprog␈↓ 201␈↓α
␈↓ ↓H␈↓The␈α
next␈αfour␈α
functions␈α
deal␈αwith␈α
functional␈αarguments.␈α
If␈α
the␈αargument␈α
is␈αa␈α
primitive,␈α
then␈αwe
␈↓ ↓H␈↓just␈α␈↓αquote␈↓␈αit;␈αthe␈αassumption␈αis␈αthat␈α
primitives␈αonly␈αaccess␈αlocal␈αvariables␈αand␈αtherefore␈α
don't␈αneed
␈↓ ↓H␈↓to␈α⊂save␈α⊂the␈α⊂environment.␈α⊂An␈α⊂expression␈α⊂which␈α⊂is␈α∂already␈α⊂␈↓αfunarg␈↓-ed␈α⊂is␈α⊂passed␈α⊂as␈α⊂is.␈α⊂ If␈α⊂it␈α⊂is␈α∂a
␈↓ ↓H␈↓λ-expression, we make a ␈↓αfunarg␈↓; otherwise we evaluate the function until we discover its character.
␈↓ ↓H␈↓αevfunction <= λ[[ ]␈↓ βHfun ← first[args];
␈↓ ↓H␈↓α␈↓ βH[isprim[] → send[mkquote[fun]];restore[cont];
␈↓ ↓H␈↓α␈↓ βH islambda[] → send[mkfunarg[fun;env]];restore[cont];
␈↓ ↓H␈↓α␈↓ βH isfunarg[] → send[fun];restore[cont];
␈↓ ↓H␈↓α␈↓ βH␈↓
t␈↓α →␈↓ ∧(save_cont[ ␈↓λ`␈↓αfun1; ␈↓λ`␈↓αpeval];
␈↓ ↓H␈↓α␈↓ βH␈↓ ∧(exp ← fun ]]
␈↓ ↓H␈↓αfun1 <= λ[[ ] send[mkfun[receive[ ]]; cont ← ␈↓λ`␈↓αev1]
␈↓ ↓H␈↓The functions ␈↓αev7␈↓ and ␈↓αev8␈↓ control the application of a ␈↓αfunarg␈↓.
␈↓ ↓H␈↓αev7 <= λ[[ ]␈↓ αxrestore[env];
␈↓ ↓H␈↓α␈↓ αxlink[];
␈↓ ↓H␈↓α␈↓ αxrestore␈↓λ'␈↓α[dest;args];
␈↓ ↓H␈↓α␈↓ αxsave_cont[ ␈↓λ`␈↓αev8; ␈↓λ`␈↓αevalargs] ]]
␈↓ ↓H␈↓αev8 <= λ[[ ] restore␈↓λ'␈↓α[env;cont]]
␈↓ ↓H␈↓Special␈α
functions␈α
are␈α
needed␈αto␈α
handle␈α
explicit␈α
calls␈αon␈α
the␈α
evaluator:␈α
␈↓αeval␈↓[<form>;<env>].␈α
We␈αset
␈↓ ↓H␈↓up␈α∞a␈α∞destination␈α∞to␈α∞receive␈α∂the␈α∞values␈α∞of␈α∞<form>␈α∞and␈α∂<env>,␈α∞and␈α∞ask␈α∞␈↓αevalargs␈↓␈α∞to␈α∂evaluate␈α∞these
␈↓ ↓H␈↓arguments. The results of the computation are seen by ␈↓αev12␈↓; this function sets up the call on ␈↓αpeval␈↓.
␈↓ ↓H␈↓αeveval <= λ[[ ]␈↓ βλsave␈↓λ'␈↓α[␈↓ βXenv;env;
␈↓ ↓H␈↓α␈↓ βλ␈↓ βXdest;alloc_dest[createvars[(G1 G2)]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ βXcont; ␈↓λ`␈↓αev12; ␈↓λ`␈↓αevalargs]]
␈↓ ↓H␈↓αev12 <= λ[[ ]␈↓ βλexp ← first_dest[];
␈↓ ↓H␈↓α␈↓ βλenv ← second_dest[];
␈↓ ↓H␈↓α␈↓ βλrestore[dest];
␈↓ ↓H␈↓α␈↓ βλsave_cont[ ␈↓λ`␈↓αev13; ␈↓λ`␈↓αpeval]]
␈↓ ↓H␈↓αev13 <= λ[[ ] restore␈↓λ'␈↓α[env;cont]] (␈↓≡␈↓α ev8)
␈↓ ↓H␈↓There␈αis␈α
a␈αsecond␈αform␈α
of␈αcall␈αon␈α
␈↓αeval␈↓␈αwhich␈α
is␈αuseful.␈αIf␈α
we␈αwrite␈α␈↓αeval␈↓[<form>],␈α
then␈αthe␈α<form>␈α
is
␈↓ ↓H␈↓evaluated in the environment which exists at the point of call. See problem on page 205.
␈↓ ↓H␈↓The␈α∩remainder␈α∪of␈α∩the␈α∩evaluator␈α∪involves␈α∩the␈α∪␈↓αprog␈↓␈α∩related␈α∩constructs.␈α∪ Several␈α∩new␈α∪ideas␈α∩are
␈↓ ↓H␈↓involved.␈α⊂As␈α⊃we␈α⊂discussed␈α⊂on␈α⊃page 196,␈α⊂we␈α⊃must␈α⊂be␈α⊂able␈α⊃to␈α⊂determine␈α⊂whether␈α⊃or␈α⊂not␈α⊃we␈α⊂are
␈↓ ↓H␈↓␈↓↓202 Imperative Constructs in LISP␈↓ 14.8␈↓
␈↓ ↓H␈↓executing␈αwithin␈αa␈α␈↓αprog␈↓:␈αwe␈αintroduced␈α␈↓αtype␈↓␈αto␈αhandle␈αthis.␈α Also␈αevery␈αexpression␈αor␈αstatement␈αin
␈↓ ↓H␈↓LISP␈αhas␈αa␈αvalue.␈αSince␈αwe␈αare␈αalways␈α
␈↓αsend␈↓-ing␈αvalues,␈αwe␈αmust␈αhave␈αa␈αdestination␈αto␈α
receive␈αthe
␈↓ ↓H␈↓values␈αcreated␈α
by␈α␈↓αprog␈↓ statements:␈αwe␈α
will␈αintroduce␈α
a␈αdummy␈αdestination␈α
which␈αwill␈αalways␈α
receive
␈↓ ↓H␈↓the␈αvalue␈αof␈αany␈αstatement.␈αThis␈αdestination␈αis␈αnamed␈α␈↓αbb␈↓,␈αfor␈α"bit bucket".␈α Finally,␈αwe␈αmust␈αhandle
␈↓ ↓H␈↓assignment␈α
statements.␈α
The␈α
innovation␈α
here␈α
is␈αthat␈α
the␈α
␈↓αsend␈↓␈α
goes␈α
to␈α
some␈α
pre-existing␈αdestination
␈↓ ↓H␈↓and␈αdestroys␈αthe␈αcurrent␈αvalue:␈αwe␈αuse␈αa␈αprimitive␈α␈↓αmkdest␈↓␈αwhose␈αeffect␈αis␈αto␈αgenerate␈αa␈αdestination
␈↓ ↓H␈↓pointer␈αto␈αthe␈αslot␈αwhich␈αis␈αto␈αreceive␈αthe␈αvalue␈αof␈αthe␈αright-hand-side␈αof␈αthe␈αassignment.␈α In␈α␈↓αevsetq␈↓
␈↓ ↓H␈↓we␈α∞use␈α∞a␈α∞function␈α∞␈↓αlookup␈↓λ'␈↓␈α∂which␈α∞is␈α∞similar␈α∞to␈α∞␈↓αlookup␈↓␈α∞except␈α∂that␈α∞it␈α∞returns␈α∞a␈α∞pointer␈α∞to␈α∂the␈α∞slot
␈↓ ↓H␈↓containing a value, rather than returning the value in the slot.
␈↓ ↓H␈↓Here are the evaluators for ␈↓αsetq␈↓ and ␈↓αset␈↓:
␈↓ ↓H␈↓αevsetq <= λ[[ ]␈↓ β_save␈↓λ'␈↓α[␈↓ βhdest;mkdest[lookup␈↓λ'␈↓α[first[args]]];
␈↓ ↓H␈↓α␈↓ β_␈↓ βhcont; ␈↓λ`␈↓αsetq1; ␈↓λ`␈↓αpeval];
␈↓ ↓H␈↓α␈↓ β_exp ← second[args]]
␈↓ ↓H␈↓αsetq1 <= λ[[ ]␈↓ αxprog[[x]␈↓ βxx ← receive[];
␈↓ ↓H␈↓α␈↓ αx␈↓ βxrestore[dest];
␈↓ ↓H␈↓α␈↓ αx␈↓ βxsend[x];
␈↓ ↓H␈↓α␈↓ αx␈↓ βxcont ← ␈↓λ`␈↓αev1 ]]
␈↓ ↓H␈↓αevset <= λ[[ ]␈↓ αxsave␈↓λ'␈↓α[args;args; cont; ␈↓λ`␈↓αset1; ␈↓λ`␈↓αpeval];
␈↓ ↓H␈↓α␈↓ αxexp ← first[args] ]
␈↓ ↓H␈↓αset1 <= λ[[ ]␈↓ αxrestore[args];
␈↓ ↓H␈↓α␈↓ αxargs ← mkass[receive[];rest[args]];
␈↓ ↓H␈↓α␈↓ αxcont ← ␈↓λ`␈↓αevsetq ]
␈↓ ↓H␈↓␈↓↓4.8␈↓ λPAn Evaluator for ␈↓αprog␈↓ 203␈↓α
␈↓ ↓H␈↓The␈α
␈↓αprog␈↓␈α
evaluator,␈α␈↓αevprog␈↓,␈α
must␈α
take␈α
cognizance␈αof␈α
all␈α
of␈α
the␈αcontrol␈α
structures␈α
which␈α
can␈αoccur
␈↓ ↓H␈↓within␈α
a␈α∞␈↓αprog␈↓.␈α
Besides␈α
ordinary␈α∞recursion,␈α
we␈α
can␈α∞have␈α
␈↓αgo␈↓s␈α
and␈α∞␈↓αreturn␈↓s.␈α
The␈α
␈↓αgo␈↓␈α∞must␈α
be␈α∞able␈α
to
␈↓ ↓H␈↓search␈α⊃the␈α∩control␈α⊃chain␈α⊃for␈α∩the␈α⊃appropriate␈α⊃label,␈α∩and␈α⊃the␈α⊃␈↓αreturn␈↓␈α∩must␈α⊃find␈α∩the␈α⊃dynamically
␈↓ ↓H␈↓enclosing␈α␈↓αprog␈↓.␈α To␈αhandle␈αeither␈αof␈αthese␈αeventualities,␈αwe␈α␈↓αsave␈↓␈αsome␈αadditional␈αinformation␈αwhen
␈↓ ↓H␈↓we␈α∞enter␈α∞a␈α
␈↓αprog␈↓.␈α∞First␈α∞we␈α
save␈α∞the␈α∞current␈α
state␈α∞of␈α∞the␈α
computation;␈α∞this␈α∞will␈α
allow␈α∞the␈α∞␈↓αreturn␈↓␈α
to
␈↓ ↓H␈↓␈↓αrestore␈↓␈α⊃everything␈α⊃as␈α⊃it␈α⊃leaves␈α∩the␈α⊃␈↓αprog␈↓.␈α⊃ Next␈α⊃we␈α⊃make␈α⊃a␈α∩new␈α⊃␈↓αenv␈↓␈α⊃which␈α⊃has␈α⊃bound␈α∩all␈α⊃the
␈↓ ↓H␈↓␈↓αprog␈↓ variables␈α∞to␈α∂␈↓α( )␈↓.␈α∞ We␈α∂save␈α∞␈↓↓that␈↓␈α∂␈↓αenv␈↓,␈α∞since␈α∂a␈α∞non-local␈α∞␈↓αgo␈↓␈α∂will␈α∞want␈α∂to␈α∞restore␈α∂that␈α∞␈↓αenv␈↓␈α∂as␈α∞it
␈↓ ↓H␈↓returns␈αfor␈αexecution.␈αFinally␈αwe␈αcreate␈αa␈α␈↓αgolist␈↓␈αwhich␈αis␈αa␈αlist␈αof␈αall␈αpoints␈αin␈αthe␈α␈↓αprog␈↓␈αwhich␈αhave
␈↓ ↓H␈↓labels.␈αThis␈αconstruct␈αallows␈αus␈αto␈αdiscover␈αquickly␈αwhich␈αlabels␈αare␈αpresent␈αin␈αthe␈α␈↓αprog␈↓␈αand␈αwhere
␈↓ ↓H␈↓they are␈↓π 139␈↓. After all this is done we are ready to execute the first line of the ␈↓αprog␈↓ body.
␈↓ ↓H␈↓αevprog <= λ[[ ]␈↓ β(save␈↓λ'␈↓α[␈↓ βxexp;exp;
␈↓ ↓H␈↓α␈↓ β(␈↓ βxenv;env;
␈↓ ↓H␈↓α␈↓ β(␈↓ βxdest;alloc_dest[prog_vars[args]];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxfun;fun;
␈↓ ↓H␈↓α␈↓ β(␈↓ βxargs;prog_body[args];
␈↓ ↓H␈↓α␈↓ β(␈↓ βxtype;PROG];
␈↓ ↓H␈↓α␈↓ β(link[];
␈↓ ↓H␈↓α␈↓ β(save␈↓λ'␈↓α[␈↓ βxenv;env;
␈↓ ↓H␈↓α␈↓ β(␈↓ βxgolist;mkgolist[args]];
␈↓ ↓H␈↓α␈↓ β(cont ← ␈↓λ`␈↓αline ]
␈↓ ↓H␈↓αmkgolist <= λ[[body] prog[[z]
␈↓ ↓H␈↓α␈↓ βxa␈↓ ∧([null[body] → return[z];
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧( islabel[first[body]] → z ← concat[body;z] ]; ␈↓π 140␈↓α
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧(body ← rest[body];
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧(go[a] ]]
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 139␈↓␈αIf␈αit␈αweren't␈αfor␈αthe␈αexistence␈αof␈αanonymous␈α␈↓αprog␈↓s␈αand␈αfunction-modifying␈αfunctions,␈αwe␈αcould
␈↓ ↓H␈↓put the responsibility of making the go-list on "<=".
␈↓ ↓H␈↓α␈↓π 140␈↓α ␈↓Note that this program handles multiply-labeled statements.
␈↓ ↓H␈↓␈↓↓204 Imperative Constructs in LISP␈↓ 14.8␈↓
␈↓ ↓H␈↓The␈α∞actual␈α∞execution␈α∞of␈α∞each␈α
line␈α∞of␈α∞a␈α∞␈↓αprog␈↓ body␈α∞is␈α∞controlled␈α
by␈α∞the␈α∞pair␈α∞␈↓αline␈↓␈α∞and␈α∞␈↓αline1␈↓.␈α
Their
␈↓ ↓H␈↓behavior␈α∂is␈α∞similar␈α∂to␈α∂that␈α∞of␈α∂␈↓αevalargs␈↓. ␈α∂␈↓αline␈↓␈α∞examines␈α∂the␈α∞next␈α∂expression;␈α∂if␈α∞there␈α∂is␈α∂no␈α∞next
␈↓ ↓H␈↓statement,␈αwe␈αexit␈αwith␈α␈↓α( )␈↓␈αusing␈α␈↓αprog_exit␈↓;␈αif␈αthe␈αnext␈αstatement␈αis␈αa␈αlabel,␈αit␈αis␈αignored;␈αotherwise
␈↓ ↓H␈↓we prepare to evaluate the expression, setting the destination to ␈↓αbb␈↓.
␈↓ ↓H␈↓αline <= λ[[ ]␈↓ αx[null[args] → prog_exit[( )];
␈↓ ↓H␈↓α␈↓ αx islabel[first[args]] → args ← rest[args];
␈↓ ↓H␈↓α␈↓ αx ␈↓
t␈↓α →␈↓ β8exp ← first[args];
␈↓ ↓H␈↓α␈↓ αx␈↓ β8dest ← bb;
␈↓ ↓H␈↓α␈↓ αx␈↓ β8save_cont[ ␈↓λ`␈↓αline1; ␈↓λ`␈↓αpeval] ]]
␈↓ ↓H␈↓αline1 <= λ[[ ]␈↓ αxargs ← rest[args];
␈↓ ↓H␈↓α␈↓ αxcont ← ␈↓λ`␈↓αline ]
␈↓ ↓H␈↓Note␈αthat␈αwe␈α
don't␈αchange␈α␈↓αcont␈↓␈α
in␈α␈↓αline␈↓␈αwhen␈αwe␈α
see␈αa␈αlabel;␈α
we␈αjust␈αleave␈αit␈α
at␈α␈↓αline␈↓␈αand␈α
␈↓αloop␈↓␈αdoes
␈↓ ↓H␈↓the rest.
␈↓ ↓H␈↓We␈α⊂call␈α⊃␈↓αprog_exit␈↓␈α⊂to␈α⊃return␈α⊂␈↓α( )␈↓␈α⊂when␈α⊃the␈α⊂body␈α⊃of␈α⊂the␈α⊂␈↓αprog␈↓␈α⊃is␈α⊂empty.␈α⊃ Thus␈α⊂the␈α⊃discussion␈α⊂of
␈↓ ↓H␈↓␈↓αprog_exit␈↓␈αinvolves␈αthe␈αsemantics␈αof␈α␈↓αreturn␈↓.␈α Of␈αthe␈αtwo␈αcontrol␈αmechanisms,␈α␈↓αreturn␈↓␈αis␈αsimpler␈αthan
␈↓ ↓H␈↓␈↓αgo␈↓.␈α
Recalling␈α
the␈α
discussion␈α
of␈α
␈↓αsave␈↓␈α
on␈α
page 188,␈α
we␈α
need␈α
to␈α
look␈α
through␈α
the␈α
␈↓αcontrol␈↓-list␈α∞for␈α
the
␈↓ ↓H␈↓last block designating a ␈↓αprog␈↓ entry. We ␈↓αrestore␈↓ to that saved state and set ␈↓αcontrol␈↓ to that prior point.
␈↓ ↓H␈↓αevreturn <= λ[[ ]␈↓ β(exp ← first[args];
␈↓ ↓H␈↓α␈↓ β(save_cont[ ␈↓λ`␈↓αret1; ␈↓λ`␈↓αpeval] ]
␈↓ ↓H␈↓αret1 <= λ[[ ] prog_exit[receive[]]]
␈↓ ↓H␈↓αprog_exit <= λ[[val]␈↓ βhcontrol ← find_prog[control];
␈↓ ↓H␈↓α␈↓ βhrestore␈↓λ'␈↓α[type;args;fun;dest;env;exp;cont];
␈↓ ↓H␈↓α␈↓ βhsend[val] ]
␈↓ ↓H␈↓The␈α∂␈↓αgo␈↓␈α∂statement␈α∂is␈α∂a␈α∂bit␈α∂more␈α∂complicated.␈α∂ When␈α∂a␈α∂␈↓αgo␈↓␈α∂statement␈α∂is␈α∂recognized,␈α∂we␈α⊂look␈α∂back
␈↓ ↓H␈↓through␈αthe␈αdynamic␈αchain␈αto␈αfind␈αthe␈αfirst␈αoccurrence␈αof␈αthe␈αdesired␈αlabel.␈αIf␈αwe␈αare␈αin␈αa␈α␈↓αprog␈↓␈αwe
␈↓ ↓H␈↓check␈αthe␈αcurrent␈α␈↓αgolist␈↓;␈α
if␈αthe␈αlabel␈αis␈αnot␈α
found,␈αor␈αif␈αwe␈αare␈α
not␈αimmediately␈αin␈αa␈α␈↓αprog␈↓,␈α
we␈αlook
␈↓ ↓H␈↓for␈αthe␈αlatest␈α␈↓αgolist␈↓␈α
and␈αsearch␈αit.␈αWe␈αcontinue␈α
this␈αprocess␈αuntil␈αwe␈α
discover␈αthe␈αlabel.␈αAt␈αthat␈α
time
␈↓ ↓H␈↓we␈α∪restore␈α∪the␈α∪environment␈α∀to␈α∪that␈α∪which␈α∪encloses␈α∪the␈α∀label,␈α∪reset␈α∪␈↓αcontrol␈↓,␈α∪and␈α∀continue␈α∪the
␈↓ ↓H␈↓computation at that point.
␈↓ ↓H␈↓αevgo <= λ[[ ]␈↓ αxexp ← first[args];
␈↓ ↓H␈↓α␈↓ αx[isconst[] →err[BAD_PROG_LABEL];
␈↓ ↓H␈↓α␈↓ αx not[isvar[]] →␈↓ ∧8save_cont[ ␈↓λ`␈↓αgo1; ␈↓λ`␈↓αpeval]
␈↓ ↓H␈↓α␈↓ αx ␈↓
t␈↓α → control ← prog_go[control;exp] ]]
␈↓ ↓H␈↓␈↓↓4.8␈↓ λPAn Evaluator for ␈↓αprog␈↓ 205␈↓α
␈↓ ↓H␈↓αprog_go <= λ[[cntrl;exp] prog[[ ]
␈↓ ↓H␈↓α␈↓ ∧_a␈↓ ∧8[eq[type;PROG] →␈↓ ε([check_go[exp;golist[cntrl]] →␈↓ (restore[env];
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ∧8␈↓ ε(␈↓ (cont ← ␈↓λ`␈↓αline;
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ∧8␈↓ ε(␈↓ (return[cntrl]
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ∧8␈↓ ε( ␈↓
t␈↓α → cntrl ← find_go[rest[cntrl]]; go[a] ];
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ∧8 ␈↓
t␈↓α → cntrl ← find_go[cntrl]; go[a] ]]]
␈↓ ↓H␈↓αcheck_go <= λ[[lab;glist]␈↓ ∧_[null[glist] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ ∧_ eq[lab;first[first[glist]]] → args ← rest[first[glist]];␈↓
t␈↓α;
␈↓ ↓H␈↓α␈↓ ∧_ ␈↓
t␈↓α → check_go[lab;rest[glist]] ]]
␈↓ ↓H␈↓The␈α
origins␈α
of␈α
the␈αinterpreter␈α
presented␈α
here␈α
can␈α
be␈αtraced␈α
from␈α
several␈α
sources:␈α[Bla 71],␈α
[Con 73],
␈↓ ↓H␈↓[Sus 75], [Ste 76b].
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I.␈α⊂ This␈α⊂problem␈α⊂involves␈α⊂the␈α⊂␈↓αescape␈↓␈α⊂expression␈α⊂discussed␈α⊂in␈α⊂[Rey 72]␈α⊂and␈α⊂implemented␈α⊂in␈α⊂the
␈↓ ↓H␈↓University of Paris's LISP [Gre 75]. We introduce the form:
␈↓ ↓H␈↓α␈↓ ∧M escape␈↓[<function>; <form␈↓β1␈↓>; ...;<form␈↓βn␈↓>]
␈↓ ↓H␈↓with␈α∞the␈α
following␈α∞semantics:␈α
we␈α∞evaluate␈α
the␈α∞<form␈↓βi␈↓>'s␈α
from␈α∞left␈α
to␈α∞right,␈α
returning␈α∞the␈α∞value␈α
of
␈↓ ↓H␈↓<form␈↓βn␈↓>␈α⊃unless␈α⊃we␈α⊂encounter␈α⊃an␈α⊃application␈α⊂involving␈α⊃<function>.␈α⊃If␈α⊂such␈α⊃an␈α⊃application␈α⊂␈↓↓does␈↓
␈↓ ↓H␈↓appear␈αwe␈αperform␈αthat␈αapplication␈αand␈αimmediately␈αreturn␈αthe␈αresulting␈αvalue␈αas␈αthe␈αvalue␈αof␈αthe
␈↓ ↓H␈↓␈↓αescape␈↓ expression.
␈↓ ↓H␈↓Extend our latest evaluator to recognize and execute the ␈↓αescape␈↓ expression.
␈↓ ↓H␈↓II.␈α⊂The␈α⊃semantics␈α⊂of␈α⊃␈↓αgo␈↓␈α⊂specified␈α⊃that␈α⊂the␈α⊂argument␈α⊃would␈α⊂be␈α⊃evaluated␈α⊂if␈α⊃it␈α⊂were␈α⊃a␈α⊂function
␈↓ ↓H␈↓application, however the current ␈↓αpeval␈↓ does not handle this case. Correct that oversight.
␈↓ ↓H␈↓III. Extend ␈↓αevcond␈↓ to handle conditional statements.
␈↓ ↓H␈↓IV.␈α
Recall␈α
our␈α∞discussion␈α
on␈α
page 188␈α∞of␈α
the␈α
implementation␈α
of␈α∞␈↓αsave␈↓␈α
and␈α
␈↓αrestore␈↓.␈α∞Implement␈α
␈↓αsave␈↓
␈↓ ↓H␈↓and ␈↓αrestore␈↓ in ␈↓αpeval␈↓.
␈↓ ↓H␈↓V. Write ␈↓αfind_go␈↓ and ␈↓αfind_prog␈↓.
␈↓ ↓H␈↓VI. Revise ␈↓αeveval␈↓ to handle calls on ␈↓αeval␈↓ with either one or two arguments. See page 201.
␈↓ ↓H␈↓VII.␈α∪Refer␈α∪to␈α∪the␈α∪problem␈α∪involving␈α∪multiple␈α∪␈↓αsetq␈↓'s␈α∪on␈α∪page 179.␈α∪ There␈α∪you␈α∪were␈α∪asked␈α∪to
␈↓ ↓H␈↓implement␈α⊃that␈α⊂feature␈α⊃using␈α⊂macros.␈α⊃ Either␈α⊂implement␈α⊃a␈α⊂macro␈α⊃facility␈α⊂in␈α⊃␈↓αpeval␈↓␈α⊃or␈α⊂explicitly
␈↓ ↓H␈↓␈↓↓206 Imperative Constructs in LISP␈↓ 14.8␈↓
␈↓ ↓H␈↓introduce␈α∀such␈α∀a␈α∀multiple␈α∃assignment␈α∀feature.␈α∀You␈α∀may␈α∃implement␈α∀that␈α∀feature␈α∀as␈α∃either␈α∀a
␈↓ ↓H␈↓sequential assignment or a parallel assignment.
␈↓ ↓H␈↓VIII.␈αRecall␈αour␈αdiscussion␈αof␈αthe␈αgeneral␈α␈↓αcatch-throw␈↓␈αpair␈αon␈αpage 184.␈α Implement␈αthese␈αfunctions
␈↓ ↓H␈↓in ␈↓αpeval␈↓.
␈↓ ↓H␈↓␈↓ ¬2␈↓↓4.9 Alternatives to ␈↓αeval␈↓␈↓α
␈↓ ↓H␈↓We␈αhave␈αseen␈αa␈αlot␈αof␈αevaluators␈αfor␈αLISP.␈αWe␈αshould␈αat␈αleast␈αlook␈αa␈αbit␈αat␈αother␈αpossibilities␈αfor
␈↓ ↓H␈↓describing␈α∀computational␈α∪behavior.␈α∀ Indeed,␈α∪what␈α∀is␈α∪"computation"?␈α∀ When␈α∪we␈α∀are␈α∀given␈α∪an
␈↓ ↓H␈↓expression␈α∞to␈α∞evaluate␈α∞we␈α∞are␈α∞really␈α∞simulating␈α∞the␈α∞application␈α∞of␈α∞simplification␈α∂and␈α∞substitution
␈↓ ↓H␈↓rules.␈α
The␈αsimplification␈α
rules␈αtell␈α
us␈αwhen␈α
an␈αexpression␈α
can␈αbe␈α
replaced␈αby␈α
another␈αexpression;
␈↓ ↓H␈↓typically␈α⊂we␈α⊂think␈α⊂of␈α⊂the␈α⊂replacing␈α⊂expression␈α⊂as␈α⊂being␈α⊂"simpler"␈α⊂than␈α⊂the␈α⊂replaced␈α⊂expression.
␈↓ ↓H␈↓Thus ␈↓αcar[(A . B)]␈↓ can be replaced by ␈↓αA␈↓, or ␈↓α[␈↓
t␈↓ → 2; ...] can be replaced by ␈↓α2␈↓.
␈↓ ↓H␈↓The␈α∃substitution␈α∀rules␈α∃typically␈α∃allow␈α∀us␈α∃to␈α∀replace␈α∃a␈α∃procedure␈α∀call␈α∃with␈α∃an␈α∀appropriately
␈↓ ↓H␈↓instantiated␈α∂copy␈α∂of␈α∂the␈α∂procedure␈α∂body.␈α∂ Thus␈α∂a␈α∂computation␈α∂involving␈α∂␈↓αappend[(A B);(2 3)]␈↓␈α∞is
␈↓ ↓H␈↓identical to that obtained by replacing the occurrence of
␈↓ ↓H␈↓α␈↓ ↓fappend[(A B);(2 3)]␈↓ by␈↓α [null[(A B)] → (2 3); ␈↓
t␈↓α → concat[first[(A B)];append[rest[(A B)];(2 3)]]]
␈↓ ↓H␈↓The␈α
result␈α
of␈α
such␈α
a␈α
substitution␈αis␈α
usually␈α
a␈α
candidate␈α
for␈α
further␈α
substitutions␈αand␈α
simplifications.
␈↓ ↓H␈↓The␈αcollection␈α
of␈αsimplification␈αand␈α
substitution␈αrules␈αis␈α
called␈αthe␈αreduction␈α
rules␈αfor␈αthe␈α
language.
␈↓ ↓H␈↓Given␈α∞an␈α∞expression,␈α∂a␈α∞computation␈α∞of␈α∂its␈α∞value␈α∞is␈α∂said␈α∞to␈α∞terminate␈α∂when␈α∞there␈α∞are␈α∂no␈α∞further
␈↓ ↓H␈↓reduction rules applicable and the reduced expression is a constant of the language.
␈↓ ↓H␈↓The␈α∞difficulties␈α∞with␈α∞these␈α
schemes␈α∞come␈α∞from␈α∞both␈α
practical␈α∞and␈α∞theoretical␈α∞considerations.␈α
The
␈↓ ↓H␈↓direct␈α
application␈α
of␈α
reduction␈α
rules␈α
is␈αquite␈α
inefficient:␈α
making␈α
textual␈α
substitutions␈α
is␈αexpensive.
␈↓ ↓H␈↓Instead␈α∞we␈α∞developed␈α∞the␈α∞ideas␈α∞of␈α∞symbol␈α
tables␈α∞to␈α∞contain␈α∞the␈α∞bindings␈α∞of␈α∞the␈α∞variables,␈α
rather
␈↓ ↓H␈↓than perform the actual substitutions.
␈↓ ↓H␈↓The␈αtheoretical␈αdifficulty␈αappears␈αsince,␈αat␈αany␈αtime␈αin␈αa␈αcomputation,␈αthere␈αmay␈αbe␈αmore␈αthan␈αone
␈↓ ↓H␈↓reduction␈α⊂rule␈α∂which␈α⊂is␈α∂applicable.␈α⊂A␈α∂further␈α⊂difficulty␈α∂is␈α⊂that␈α∂one␈α⊂sequence␈α∂of␈α⊂reductions␈α∂may
␈↓ ↓H␈↓terminate,␈α
while␈α
another␈αsequence␈α
of␈α
reductions␈α
is␈αnon-terminating.␈α
We␈α
have␈α
seen␈αthis␈α
phenomenon
␈↓ ↓H␈↓in␈α∩previous␈α∩discussions␈α⊃of␈α∩call-by-value␈α∩versus␈α⊃call-by-name,␈α∩inner-most␈α∩versus␈α∩outer-most,␈α⊃and
␈↓ ↓H␈↓normal order reductions versus applicative order reductions.
␈↓ ↓H␈↓Though␈α
LISP␈α
opted␈α
for␈αthe␈α
call-by-value␈α
interpretation␈α
of␈α
expressions,␈αit␈α
is␈α
possible␈α
to␈α
develop␈αa
␈↓ ↓H␈↓call-by-name␈αevaluator.␈α
Call-by-name␈αimplies␈α
that␈αwe␈αsubstitute␈α
the␈αunevaluated␈α
actual␈αparameters
␈↓ ↓H␈↓for␈αthe␈αformal␈αparameters.␈α As␈αin␈α␈↓αeval␈↓,␈αwe␈αneed␈αnot␈αmake␈αexplicit␈αsubstitutions;␈αappropriate␈αuse␈αof
␈↓ ↓H␈↓symbol␈α⊃tables␈α⊃will␈α⊂simulate␈α⊃the␈α⊃action,␈α⊂but␈α⊃now,␈α⊃when␈α⊃we␈α⊂build␈α⊃a␈α⊃symbol␈α⊂table␈α⊃on␈α⊃entry␈α⊃to␈α⊂a
␈↓ ↓H␈↓λ-expression␈αwe␈α
bind␈αthe␈αactual␈α
expressions␈αto␈αthe␈α
λ-variables.␈α When␈αwe␈α
encounter␈αa␈α
variable␈αin
␈↓ ↓H␈↓the␈α⊃body␈α⊂of␈α⊃the␈α⊃expression␈α⊂we␈α⊃evaluate␈α⊂the␈α⊃actual␈α⊃parameter.␈α⊂The␈α⊃difficulty␈α⊂is␈α⊃that␈α⊃an␈α⊂actual
␈↓ ↓H␈↓␈↓↓4.9␈↓ λxAlternatives to ␈↓αeval␈↓ 207␈↓α
␈↓ ↓H␈↓parameter␈α
itself␈α
may␈α
contain␈α
variables,␈α
and␈α
those␈α
variables␈α
need␈α
to␈α
be␈α
interpreted␈α
in␈α
the␈αbinding
␈↓ ↓H␈↓environment. This means that we must bind ␈↓αfunarg␈↓-like expressions to the formal parameters.
␈↓ ↓H␈↓Most␈α∂of␈α⊂␈↓αeval␈↓βname␈↓␈α∂is␈α∂like␈α⊂␈↓αeval␈↓␈α∂of␈α⊂Section 3.5,␈α∂so␈α∂we␈α⊂only␈α∂sketch␈α∂the␈α⊂interesting␈α∂parts.␈α⊂Assume␈α∂the
␈↓ ↓H␈↓␈↓αfunarg␈↓-expression␈α∨we␈α manufacture␈α∨has␈α∨two␈α components,␈α∨the␈α∨␈↓αexpr␈↓-component,␈α and␈α∨the
␈↓ ↓H␈↓␈↓αenv␈↓-component.
␈↓ ↓H␈↓We␈α∩can␈α⊃implement␈α∩␈↓αeval␈↓βname␈↓␈α⊃by␈α∩simply␈α∩changing␈α⊃the␈α∩symbol␈α⊃table␈α∩orgainzation,␈α∩supplying␈α⊃new
␈↓ ↓H␈↓versions of ␈↓αlookup␈↓ and ␈↓αmkenv␈↓. See page 109 and page 137.
␈↓ ↓H␈↓α␈↓ ¬Salloc <= λ[[vars] ()]
␈↓ ↓H␈↓α␈↓ ∧ send <= λ[[var;val;dest] concat[mkent[var;val];dest]
␈↓ ↓H␈↓α␈↓ ∧elink <= λ[[dest;env] concat[dest;env]]
␈↓ ↓H␈↓αlookup <= λ[[var;env] l␈↓λ'␈↓α[var;first[env];rest[env]]
␈↓ ↓H␈↓αl␈↓λ'␈↓α <= λ[[n;bl;env]␈↓ β8[null[bl] → l␈↓λ'␈↓α[n;first[env];rest[env]]
␈↓ ↓H␈↓α␈↓ β8 eq[n;name[first[bl]] → eval[value[first[bl]];env]
␈↓ ↓H␈↓α␈↓ β8 ␈↓
t␈↓α → l␈↓λ'␈↓α[n;rest[bl];env] ]]
␈↓ ↓H␈↓One␈αadvantage␈αof␈αsuch␈αan␈αevaluator␈αis␈αthat␈αit␈αwill␈αnot␈αevaluate␈αa␈αparameter␈αuntil␈αit␈αactually␈αneeds
␈↓ ↓H␈↓it,␈αwhereas␈α␈↓αeval␈↓␈αevaluates␈αall␈αparameters␈αat␈αfunction␈αentry␈αtime.␈αIf␈αan␈αactual␈αparameter␈αis␈α
not␈αused
␈↓ ↓H␈↓in␈α∂the␈α∂computation␈α∂and␈α∂the␈α∂computation␈α∂of␈α∂that␈α∂parameter␈α∂fails␈α∂to␈α∂terminate,␈α∂then␈α⊂␈↓αeval␈↓βname␈↓␈α∂will
␈↓ ↓H␈↓terminate␈αwhile␈α␈↓αeval␈↓␈αwill␈αnot.␈α There␈αare␈αdisadvantages␈αto␈α␈↓αeval␈↓βname␈↓.␈αEvery␈αoccurrence␈αof␈αa␈αvariable
␈↓ ↓H␈↓within␈αthe␈αbody␈αof␈α
the␈αfunction␈αwill␈αinvolve␈αa␈α
re-evaluation␈αof␈αthe␈αcorresponding␈αactual␈α
parameter.
␈↓ ↓H␈↓If␈αthere␈α
are␈αno␈αside-effects␈α
in␈αthe␈αcomputation␈α
then␈αthese␈αrepeated␈α
computations␈αare␈αan␈α
unnecessary
␈↓ ↓H␈↓expense.␈α_Several␈α_people␈α_([Wad 71],␈α_[Vui 74],␈α_[Pac 73],␈α_[Hen 76],␈α_[Fri 76a])␈α_have␈α↔suggested
␈↓ ↓H␈↓modifications␈α∩to␈α∩␈↓αeval␈↓βname␈↓␈α∩to␈α⊃reduce␈α∩the␈α∩inefficiency.␈α∩ The␈α⊃basic␈α∩idea,␈α∩named␈α∩call-by-need␈α∩is␈α⊃to
␈↓ ↓H␈↓proceed␈α
in␈α
the␈α
␈↓αeval␈↓βname␈↓␈α
style␈α∞until␈α
the␈α
first␈α
use␈α
of␈α
a␈α∞variable.␈α
At␈α
that␈α
time␈α
we␈α
evaluate␈α∞the␈α
actual
␈↓ ↓H␈↓parameter,␈α∂and␈α∂modify␈α∞the␈α∂symbol␈α∂table,␈α∞␈↓↓replacing␈↓␈α∂the␈α∂actual␈α∞parameter␈α∂with␈α∂its␈α∂value.␈α∞Further
␈↓ ↓H␈↓references␈α∞to␈α∞that␈α∞variable␈α∞simply␈α∞get␈α∞the␈α∞value.␈α∞Obviously␈α∞the␈α∞scheme␈α∞will␈α∞not␈α∞work␈α∞correctly␈α
if
␈↓ ↓H␈↓side-effects are present. We leave it to the reader to supply the details of ␈↓αeval␈↓βneed␈↓; see page 210.
␈↓ ↓H␈↓We␈αnow␈αexplore␈αa␈αdifferent␈αkind␈αof␈αmodification␈αto␈αLISP.␈αThis␈αone␈αis␈αgrounded␈αmore␈αin␈αpractical
␈↓ ↓H␈↓experience␈α
with␈αthe␈α
programming␈αlanguage,␈α
though␈αthe␈α
results␈αdo␈α
have␈αtheoretical␈α
interest.␈α
It␈αhas
␈↓ ↓H␈↓been␈α∂noted␈α∂that␈α∞programmers␈α∂frequently␈α∂wish␈α∞to␈α∂return␈α∂more␈α∞than␈α∂one␈α∂value␈α∞as␈α∂the␈α∂result␈α∂of␈α∞a
␈↓ ↓H␈↓function␈α
application.␈α
The␈α
standard␈αalternatives␈α
in␈α
LISP␈α
are␈αeither␈α
to␈α
make␈α
global␈αassignments␈α
from
␈↓ ↓H␈↓within␈α
the␈α
body␈α
of␈αthe␈α
function,␈α
or␈α
to␈αreturn␈α
a␈α
list␈α
of␈α
the␈αdesired␈α
values␈α
making␈α
it␈αthe␈α
responsibility
␈↓ ↓H␈↓of␈α∞the␈α∞calling␈α∞program␈α∞to␈α∞select␈α∞the␈α∞proper␈α∞components.␈α∞ Neither␈α∞alternative␈α∞is␈α∂particularly␈α∞good.
␈↓ ↓H␈↓Programming␈α∃with␈α∃extensive␈α∀side-effects␈α∃tends␈α∃to␈α∀lead␈α∃to␈α∃obscure␈α∀programs␈α∃and␈α∃may␈α∀incur
␈↓ ↓H␈↓unnecessary␈α⊃complications␈α∩in␈α⊃debugging;␈α⊃see␈α∩Section 6.23.␈α⊃Passing␈α⊃lists␈α∩back␈α⊃as␈α∩values␈α⊃requires
␈↓ ↓H␈↓much␈α∞additional␈α∞computation:␈α∞someone␈α∞must␈α∞build␈α∞the␈α∞list;␈α∞someone␈α∞must␈α∞tear␈α∞it␈α∞apart.␈α∞It␈α∞is␈α∞also
␈↓ ↓H␈↓disturbing␈αthat␈αthe␈αoperation␈αbeing␈αmodelled,␈α--multiple-values--,␈αis␈αnot␈αrecognizable␈αas␈αa␈αconstruct.
␈↓ ↓H␈↓␈↓↓208 Imperative Constructs in LISP␈↓ 24.9␈↓
␈↓ ↓H␈↓This␈α∩is␈α∩a␈α⊃similar␈α∩complaint␈α∩to␈α∩that␈α⊃we␈α∩raised␈α∩in␈α⊃discussing␈α∩labels-and-␈↓αgo␈↓s␈α∩versus␈α∩an␈α⊃iterative
␈↓ ↓H␈↓construct.
␈↓ ↓H␈↓Our␈α⊃goal␈α⊃is␈α⊃realizable␈α⊃by␈α⊃a␈α⊃slight␈α⊃extension␈α⊃of␈α⊃the␈α⊃extended␈α⊃conditionals␈α⊃and␈α⊃multiple-bodied
␈↓ ↓H␈↓λ-expressions (page 180, page 182).
␈↓ ↓H␈↓We will interpret the form:
␈↓ ↓H␈↓␈↓ ¬}p␈↓βi␈↓ → e␈↓βi1␈↓; ... e␈↓βin␈↓
␈↓ ↓H␈↓so␈αas␈αto␈α
return␈αthe␈αe␈↓βij␈↓-values␈αto␈α
the␈αcalling␈αfunction␈α
in␈αa␈αleft-to-right␈αorder.␈α
If␈αthe␈αcalling␈αprogram␈α
is
␈↓ ↓H␈↓single-valued␈α∩then␈α∩the␈α∩value␈α∩it␈α∩sees␈α∩is␈α∪the␈α∩value␈α∩of␈α∩e␈↓βin␈↓.␈α∩This␈α∩is␈α∩compatible␈α∩with␈α∪our␈α∩current
␈↓ ↓H␈↓interpretation.
␈↓ ↓H␈↓The evaluation of:
␈↓ ↓H␈↓␈↓ ¬.␈↓αλ[[ ... ] f␈↓β1␈↓α[ ... ]; ...; f␈↓βn␈↓α[ ... ]]␈↓
␈↓ ↓H␈↓will be interpreted similarly.
␈↓ ↓H␈↓For␈α∞example␈α∞[Fri 76b]␈α
discusses␈α∞a␈α∞multiple-valued␈α
function␈α∞named␈α∞␈↓αsigmasum␈↓.␈α
This␈α∞function␈α∞is␈α
to
␈↓ ↓H␈↓take␈αa␈αlist␈αof␈αnumbers␈αand␈αreturn␈αthree␈αitems:␈αthe␈αlength␈αof␈αthe␈αlist,␈αthe␈αsum␈αof␈αthe␈αnumbers␈αin␈αthe
␈↓ ↓H␈↓list,␈α∂and␈α⊂the␈α∂sum␈α∂of␈α⊂the␈α∂squares␈α⊂of␈α∂the␈α∂numbers␈α⊂in␈α∂the␈α⊂list.␈α∂ In␈α∂our␈α⊂notation␈α∂␈↓αsigmasum␈↓␈α⊂can␈α∂be
␈↓ ↓H␈↓expressed as:
␈↓ ↓H␈↓αsigmasum <= λ[[x]␈↓ β8[null[x] → 0;0;0;
␈↓ ↓H␈↓α␈↓ β8 ␈↓
t␈↓α → λ[␈↓ ∧_[z␈↓β1␈↓α;z␈↓β2␈↓α;z␈↓β3␈↓α]␈↓ ¬_add1[z␈↓β1␈↓α];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬_plus[first[x];z␈↓β2␈↓α];
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_␈↓ ¬_plus[times[first[x];first[x]];z␈↓β3␈↓α] ]
␈↓ ↓H␈↓α␈↓ β8␈↓ ∧_[sigmasum[rest[x]]] ]]
␈↓ ↓H␈↓Notice␈α∞that␈α∞we␈α∞use␈α∞an␈α∂anonymous␈α∞λ-expression␈α∞to␈α∞spread␈α∞the␈α∂multiple␈α∞values␈α∞at␈α∞the␈α∞level␈α∂of␈α∞the
␈↓ ↓H␈↓caller.
␈↓ ↓H␈↓␈↓↓4.9␈↓ λxAlternatives to ␈↓αeval␈↓ 209␈↓α
␈↓ ↓H␈↓Another␈αexample␈α
is␈αa␈α
solution␈αto␈α
the␈α␈↓αsamefringe␈↓␈α
problem [Hew 74]:␈αdetermine␈α
whether␈αor␈α
not␈αthe
␈↓ ↓H␈↓terminal␈α∂nodes␈α∂of␈α∂two␈α∞trees␈α∂are␈α∂the␈α∂same,␈α∂respecting␈α∞order,␈α∂but␈α∂irrespective␈α∂of␈α∂tree␈α∞structure␈↓π 141␈↓.
␈↓ ↓H␈↓Thus:
␈↓ ↓H␈↓α␈↓ α←samefringe[(A (B (C))); (A B C)] = ␈↓
t␈↓ but ␈↓αsamefringe[(A (B C)); (A C B)] = ␈↓
f␈↓.
␈↓ ↓H␈↓αsamefringe <= λ[[x;y]␈↓ βh[null[x] → null[y];
␈↓ ↓H␈↓α␈↓ βh ␈↓
t␈↓α →␈↓ ∧8λ[[z␈↓β1␈↓α;z␈↓β2␈↓α;z␈↓β3␈↓α;z␈↓β4␈↓α][eq[z␈↓β1␈↓α;z␈↓β3␈↓α] → samefringe[z␈↓β2␈↓α;z␈↓β4␈↓α]; ␈↓
t␈↓α → ␈↓
f␈↓α]]
␈↓ ↓H␈↓α␈↓ βh␈↓ ∧8 [fringe[x];fringe[y]] ]
␈↓ ↓H␈↓αfringe <= λ[[x]␈↓ β_[atom[first[x]] → first[x]; rest[x];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α →␈↓ βxλ[[y;z] y;␈↓ ∧x[null[z] → rest[x];
␈↓ ↓H␈↓α␈↓ β_␈↓ βx␈↓ ∧x ␈↓
t␈↓α → cons[z; rest[x]] ] ]
␈↓ ↓H␈↓α␈↓ β_␈↓ βx [fringe[first[x]]] ] ]
␈↓ ↓H␈↓In␈α
this␈α
solution,␈α␈↓αsamefringe␈↓␈α
is␈α
single-valued␈αbut␈α
uses␈α
values␈αfrom␈α
a␈α
multiple-valued␈α
function.␈αThe
␈↓ ↓H␈↓two␈αvalues␈αfrom␈α␈↓αfringe[x]␈↓␈αare␈αspread␈αinto␈α␈↓αz␈↓β1␈↓␈αand␈α␈↓αz␈↓β2␈↓␈αand␈αthe␈αvalues␈αfrom␈α␈↓αfringe[y]␈↓␈αare␈αspread␈αinto
␈↓ ↓H␈↓␈↓αz␈↓β3␈↓ and ␈↓αz␈↓β4␈↓.
␈↓ ↓H␈↓It␈αis␈αeasy␈αto␈αwrite␈αan␈αevaluator␈αfor␈αsuch␈αmultiple-valued␈αexpressions.␈α Here␈αis␈αa␈αsketch␈αof␈αthe␈αbasic
␈↓ ↓H␈↓parts:
␈↓ ↓H␈↓αmeval <= λ[[x;e]␈↓ β([isconst[x] → list[denote[x]];
␈↓ ↓H␈↓α␈↓ β( isvar[x] →list[lookup[x;e]];
␈↓ ↓H␈↓α␈↓ β( iscond[x] → mevcond[condbody[x];e];
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → mapply[fun[x];mevlist[arglist[x];e];e] ]]
␈↓ ↓H␈↓αmapply <= λ[[fn;args;e]␈↓ ∧_[isprim[fun] →list[apply[fun;args;e]]
␈↓ ↓H␈↓α␈↓ ∧_ islambda[fun] → mevlist[␈↓ εXbodylist[fun];
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ¬X␈↓ εXmkenv[vars[fun];args;e] ]
␈↓ ↓H␈↓α␈↓ ∧_ ␈↓
t␈↓α → mapply[eval[fun;e];args;e] ]]
␈↓ ↓H␈↓αmevlist <= λ[[l;e]␈↓ β([null[l] → ();
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → append[meval[first[l];e]; mevlist[rest[l];e]] ]]
␈↓ ↓H␈↓αmevcond <= λ[[l;e]␈↓ βH[null[l] → ();
␈↓ ↓H␈↓α␈↓ βH first[meval[pred[first[l]];e]] → mevlist[conseq[first[l];env];
␈↓ ↓H␈↓α␈↓ βH ␈↓
t␈↓α → mevcond[rest[l];e] ]]
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 141␈↓␈α
There␈α
are␈α
many␈α
"solutions"␈α
to␈α
this␈α
problem;␈α
the␈α
simplest␈α
is␈α
to␈α
flatten␈α
the␈α
trees␈α
first,␈α
then␈α
use
␈↓ ↓H␈↓␈↓αequal␈↓.␈α⊃Indeed,␈α⊂there␈α⊃are␈α⊂many␈α⊃"problems";␈α⊂the␈α⊃most␈α⊂accurate␈α⊃formulation␈α⊂requires␈α⊃that␈α⊃no␈α⊂␈↓αcons␈↓
␈↓ ↓H␈↓operations␈αbe␈αdone.␈αFor␈αmore␈αdetails␈αand␈αinteresting␈αdiscussions␈αsee␈α[Gre 76],␈α[Hen 76],␈α[And 76a],
␈↓ ↓H␈↓and [Fin 76].
␈↓ ↓H␈↓␈↓↓210 Imperative Constructs in LISP␈↓ 24.9␈↓
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Complete the specification of ␈↓αeval␈↓βname␈↓.
␈↓ ↓H␈↓II.␈α∞Complete␈α∂the␈α∞specification␈α∞of␈α∂␈↓αeval␈↓βneed␈↓.␈α∞To␈α∂do␈α∞this,␈α∞you␈α∂may␈α∞assume␈α∞the␈α∂existence␈α∞of␈α∂a␈α∞binary
␈↓ ↓H␈↓function␈αnamed␈α␈↓αstuff␈↓␈αwhose␈αfirst␈αargument␈α␈↓αx␈↓␈αis␈αthe␈αa␈αname␈αin␈αthe␈αsymbol␈αtable,␈αand␈αwhose␈αsecond
␈↓ ↓H␈↓argument ␈↓αy␈↓ is a value. ␈↓αstuff␈↓ is to replace the current binding of ␈↓αx␈↓ with ␈↓αy␈↓.
␈↓ ↓H␈↓III. Modify ␈↓αpeval␈↓ to handle multiple-valued functions.
␈↓ ↓H␈↓IV.␈α
Recall␈α
problem␈α
II␈αon␈α
page 139␈α
dealing␈α
with␈α
the␈αanalysis␈α
of␈α
␈↓αlookup␈↓.␈α
Include␈α
call-by-name␈αand
␈↓ ↓H␈↓call-by-need in your analysis.
␈↓ ↓H␈↓V.␈α∞Using␈α∞the␈α∞results␈α∞of␈α
the␈α∞previous␈α∞problem,␈α∞make␈α∞up␈α∞a␈α
table␈α∞whose␈α∞rows␈α∞are␈α∞labeled␈α∞with␈α
the
␈↓ ↓H␈↓binding␈αimplementations:␈α"deep"␈α"shallow",␈α"Weizenbaum",␈α"need",␈αand␈α"name";␈αand␈αwhose␈αcolumns
␈↓ ↓H␈↓are labeled with the prmitives: ␈↓αalloc␈↓, ␈↓αlink␈↓, ␈↓αsend␈↓, and the primitives for ␈↓αlookup␈↓. Supply the entries.
␈↓ ↓H␈↓␈↓ ¬≡␈↓↓4.10 Function Definitions␈↓
␈↓ ↓H␈↓Now␈αthat␈αwe␈αhave␈αdeveloped␈αthese␈αmore␈α
explicit␈αevaluators,␈αwe␈αshould␈αbe␈αable␈αto␈αexploit␈α
some␈αof
␈↓ ↓H␈↓this␈α
additional␈α∞detail.␈α
In␈α
particular,␈α∞more␈α
of␈α∞the␈α
detail␈α
of␈α∞"<="␈α
should␈α
be␈α∞apparent.␈α
The␈α∞effect␈α
of
␈↓ ↓H␈↓␈↓αf <= λ[[x] ␈↓λx␈↓α]␈↓␈α∞is␈α∞to␈α∞put␈α∞the␈α
definition␈α∞of␈α∞␈↓αf␈↓␈α∞in␈α∞the␈α
global␈α∞environment,␈α∞whereas␈α∞␈↓αlabel␈↓␈α∞creates␈α∞a␈α
new
␈↓ ↓H␈↓dest-block␈α∞with␈α∞␈↓αf␈↓␈α∞bound␈α∞to␈α∞a␈α∞␈↓αfunarg␈↓␈α∞consisting␈α∞of␈α∞␈↓λx␈↓␈α∞and␈α∞that␈α∞constructed␈α∞environment.␈α∞Once␈α
we
␈↓ ↓H␈↓leave␈αthe␈αenvironment␈αcontaining␈αthe␈α␈↓αlabel␈↓␈αdefinition,␈αthat␈αdefinition␈αis␈αeffectively␈α
destroyed.␈α The
␈↓ ↓H␈↓effect␈α
of␈α
"<="␈α
is␈α
to␈α
be␈α
global.␈α
A␈α
"<="-definition␈α
could␈α
be␈α
temporarily␈α
superseded␈α
by␈α
a␈α
␈↓αlabel␈↓-definition
␈↓ ↓H␈↓to␈α∀the␈α∀same␈α∀name␈α∀and␈α∀therefore␈α∀our␈α∀search␈α∪for␈α∀a␈α∀binding␈α∀for␈α∀␈↓αf␈↓␈α∀may␈α∀not␈α∀short-circuit␈α∪the
␈↓ ↓H␈↓environment chain.
␈↓ ↓H␈↓Our␈αsearch␈αstrategy␈αis␈αencoded␈αin␈αthe␈α␈↓αlookup␈↓␈αfunction;␈αusing␈αthe␈αcurrent␈αenvironment,␈αwe␈αfind␈αthe
␈↓ ↓H␈↓latest␈αbinding␈αfor␈α
a␈αvariable.␈α With␈αthe␈α
␈↓αprog␈↓␈αevaluator,␈α␈↓αpeval␈↓β1␈↓␈αof␈α
page 199,␈αthings␈αhave␈α
become␈αa
␈↓ ↓H␈↓bit␈α
more␈αcomplicated.␈α
Besides␈α
finding␈αthe␈α
definition␈αwe␈α
must␈α
also␈αdetermine␈α
whether␈αthe␈α
arguments
␈↓ ↓H␈↓are␈αto␈αbe␈αevaluated.␈α The␈αdevice␈αof␈α␈↓αisspec␈↓␈α(page 197)␈αis␈αsufficient␈αfor␈αthe␈αevaluators,␈αbut␈αhas␈αsome
␈↓ ↓H␈↓difficulties␈αif␈αwe␈αwish␈αto␈αallow␈αuser-defined␈αspecial␈αforms.␈αWe␈αwill␈αdevelop␈αa␈αsyntax␈αfor␈αexpressing
␈↓ ↓H␈↓special forms at the user level, and then discuss problems of implementation.
␈↓ ↓H␈↓We␈αwill␈αdefine␈α"<␈↓βf␈↓="␈αto␈αmean␈α"..is␈αdefined␈αto␈αbe␈αa␈αspecial␈αform...".␈α A␈αspecial-form␈αdefinition␈αis␈αalso
␈↓ ↓H␈↓called a ␈↓↓fexpr␈↓; and a call-by-value definition is called an ␈↓↓expr␈↓.
␈↓ ↓H␈↓A␈αfexpr␈αis␈αdefined␈αwith␈αeither␈αone␈αor␈αtwo␈αformal␈αparameters.␈αThe␈αfirst␈αparameter␈αis␈αalways␈αbound
␈↓ ↓H␈↓to␈αthe␈αlist␈αof␈α␈↓↓unevaluated␈↓␈αactual␈αparameters.␈α If␈αthe␈αdefinition␈αhas␈αa␈αsecond␈αformal␈αparameter,␈αthen
␈↓ ↓H␈↓the␈αenvironment␈αat␈αthe␈αpoint␈αof␈αcall␈αis␈αassigned␈αto␈αthe␈αsecond␈αparameter.␈α This␈αdistinction␈αneeds␈αto
␈↓ ↓H␈↓␈↓↓4.10␈↓ λ\Function Definitions 211␈↓
␈↓ ↓H␈↓be␈α⊂made␈α⊃if␈α⊂we␈α⊂expect␈α⊃to␈α⊂perform␈α⊂some␈α⊃evaluation␈α⊂of␈α⊂the␈α⊃formal␈α⊂parameters␈α⊂within␈α⊃the␈α⊂fexpr.
␈↓ ↓H␈↓Using␈αthe␈αimplementation␈αof␈α␈↓αeval␈↓␈αdiscussed␈αon␈αpage 201␈αwe␈αcan␈αwrite␈αeither␈α␈↓αeval[␈↓<form>;<env>]␈αor
␈↓ ↓H␈↓␈↓αeval␈↓[<form>].␈αIn␈αthe␈αlatter␈αcase␈αthe␈αenvironment␈αthat␈αis␈αused␈αis␈αthe␈αenvironment␈αwhich␈αwas␈αcurrent
␈↓ ↓H␈↓when the ␈↓αeval␈↓ is performed. Sometimes this is not the desired environment. Consider:
␈↓ ↓H␈↓α␈↓ βxf1 <␈↓βf␈↓α= λ[[x] prog[[y]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬hy ← 2;
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬hreturn[eval[first[x]]]]
␈↓ ↓H␈↓If␈α
we␈α
execute␈α
␈↓αf1[0]␈↓,␈α
␈↓αx␈↓␈α
will␈α
be␈α
bound␈α
to␈αthe␈α
list␈α
␈↓α(0)␈↓␈α
and␈α
␈↓αeval[first[x]]␈↓␈α
will␈α
return␈α
␈↓α0␈↓␈α
as␈α
expected.␈αBut␈α
if
␈↓ ↓H␈↓we execute:
␈↓ ↓H␈↓α␈↓ βxy ← 0;
␈↓ ↓H␈↓α␈↓ βxf1[y];
␈↓ ↓H␈↓then␈α␈↓αx␈↓␈αgets␈αbound␈αto␈α␈↓α(Y)␈↓,␈αand␈α␈↓αeval[Y]␈↓␈αwill␈αfind␈αthe␈αvalue␈αassociated␈αwith␈α␈↓αY␈↓␈αto␈αbe␈α␈↓α2␈↓,␈αand␈αthe␈αvalue
␈↓ ↓H␈↓of ␈↓αf1[y]␈↓ is ␈↓α2␈↓, rather than the expected ␈↓α0␈↓.
␈↓ ↓H␈↓The␈αproblem␈αis␈αthat␈αthe␈αcall␈α
on␈α␈↓αeval␈↓␈αtakes␈αplace␈αin␈αthe␈α
wrong␈αenvironment.␈α We␈αcan␈αcorrect␈αthis␈α
by
␈↓ ↓H␈↓making␈αthe␈αdefinition␈αwith␈α␈↓↓two␈↓␈αarguments,␈αbinding␈αthe␈αsecond␈αto␈αthe␈αenvironment␈αat␈αthe␈αpoint␈αof
␈↓ ↓H␈↓call to the fexpr:
␈↓ ↓H␈↓α␈↓ βxf2 <␈↓βf␈↓α= λ[[x;a] prog[[y]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬Hy ← 2;
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬Hreturn[eval[first[x];a]]]
␈↓ ↓H␈↓α␈↓ βxy ← 0;
␈↓ ↓H␈↓α␈↓ βxf2[y];
␈↓ ↓H␈↓The call on ␈↓αf2␈↓ will use the environment with ␈↓αy␈↓ being ␈↓α0␈↓ rather than ␈↓α2␈↓.
␈↓ ↓H␈↓As a final example:
␈↓ ↓H␈↓α␈↓ βxf3 <␈↓βf␈↓α= λ[[x;a] prog[[z]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬Hy ← 2;
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬Hreturn[eval[first[x];a]]]
␈↓ ↓H␈↓α␈↓ βxy ← 0;
␈↓ ↓H␈↓α␈↓ βxf3[y];
␈↓ ↓H␈↓would return ␈↓α2␈↓.
␈↓ ↓H␈↓As␈α
we␈α
have␈αjust␈α
seen,␈α
special␈αforms␈α
must␈α
be␈α
used␈αwith␈α
care.␈α
However,␈αthey␈α
are␈α
useful␈α
in␈αseveral
␈↓ ↓H␈↓contexts.␈α∀Recall␈α∀that␈α∃we␈α∀restricted␈α∀LISP␈α∃call-by-value␈α∀functions␈α∀to␈α∃have␈α∀a␈α∀fixed␈α∃number␈α∀of
␈↓ ↓H␈↓arguments.␈α∞For␈α
example␈α∞if␈α∞we␈α
wish␈α∞to␈α∞add␈α
four␈α∞numbers␈α∞or␈α
append␈α∞three␈α∞lists␈α
we␈α∞have␈α∞to␈α
write
␈↓ ↓H␈↓something like:
␈↓ ↓H␈↓α␈↓ βhplus[x␈↓β1␈↓α;[plus[x␈↓β2␈↓α;plus[x␈↓β3␈↓α;x␈↓β4␈↓α]␈↓ or ␈↓αappend[append[l␈↓β1␈↓α;l␈↓β2␈↓α];l␈↓β3␈↓α]
␈↓ ↓H␈↓␈↓↓212 Imperative Constructs in LISP␈↓ &4.10␈↓
␈↓ ↓H␈↓Since ␈↓αplus␈↓ and ␈↓αappend␈↓ are associative operations we would rather write:
␈↓ ↓H␈↓α␈↓ ∧iplus[x␈↓β1␈↓α;x␈↓β2␈↓α;x␈↓β3␈↓α;x␈↓β4␈↓α]␈↓ or ␈↓αappend[l␈↓β1␈↓α;l␈↓β2␈↓α;l␈↓β3␈↓α]
␈↓ ↓H␈↓We␈α
discussed␈αthe␈α
macro␈αimplementation␈α
of␈αthese␈α
constructs␈αin␈α
Section 3.12.␈α Using␈α
a␈α
special␈αform,
␈↓ ↓H␈↓we could write ␈↓αplus␈↓ as:
␈↓ ↓H␈↓αplus <␈↓βf␈↓α= λ[␈↓ αX[l;e] prog[[sum]
␈↓ ↓H␈↓α␈↓ αX␈↓ αxsum ← 0;
␈↓ ↓H␈↓α␈↓ αXa␈↓ αx[null[l] → return[sum]];
␈↓ ↓H␈↓α␈↓ αX␈↓ αxsum ← *plus[sum;eval[first[l];e]];
␈↓ ↓H␈↓α␈↓ αX␈↓ αxl ← rest[l];
␈↓ ↓H␈↓α␈↓ αX␈↓ αxgo[a]]]
␈↓ ↓H␈↓Notice␈αthat␈αwe␈αcould␈αhave␈αused␈α␈↓αeval␈↓␈αwith␈αone␈αargument␈αunless␈αthe␈αvariables␈α␈↓αl␈↓␈αor␈α␈↓αsum␈↓␈αappeared␈αas
␈↓ ↓H␈↓constitutents of the actual parameters.
␈↓ ↓H␈↓Recalling␈αSection 3.12,␈αwe␈αcan␈αuse␈α<␈↓βf␈↓=␈αto␈αextend␈αthe␈αevaluator.␈α For␈αexample,␈α␈↓αand␈↓␈αcould␈αbe␈αdefined
␈↓ ↓H␈↓as:
␈↓ ↓H␈↓␈↓ β:␈↓αand <␈↓βf␈↓α= λ[[l;e] evand[l;e]] ␈↓where ␈↓αevand␈↓ is defined on page 140.
␈↓ ↓H␈↓The␈α
implementation␈α∞of␈α
␈↓αg <␈↓βf␈↓= ␈↓αλ[[x] ␈↓λx␈↓]␈α∞requires␈α
that␈α∞we␈α
represent␈α∞the␈α
fact␈α∞that␈α
␈↓αg␈↓␈α∞is␈α
a␈α∞fexpr␈α
rather
␈↓ ↓H␈↓than␈αan␈αexpr.␈αThe␈αimplication␈αof␈α␈↓αisspec␈↓␈αof␈αpage 197␈αis␈αthat␈αwe␈αhave␈αtwo␈αtables:␈αone␈αfor␈αexprs,␈αone
␈↓ ↓H␈↓for␈α∂fexprs.␈α∂This␈α∂complicates␈α∂the␈α∂search␈α∞strategy␈α∂unnecessarily.␈α∂ Indeed␈α∂there␈α∂should␈α∂only␈α∂be␈α∞one
␈↓ ↓H␈↓definition␈α⊂or␈α⊃value␈α⊂associated␈α⊂with␈α⊃a␈α⊂name␈α⊂at␈α⊃any␈α⊂one␈α⊂time,␈α⊃so␈α⊂a␈α⊂single␈α⊃table␈α⊂should␈α⊃be␈α⊂both
␈↓ ↓H␈↓necessary␈α
and␈α∞sufficient.␈α
We␈α∞␈↓↓do␈↓␈α
need␈α∞some␈α
way␈α
of␈α∞determining␈α
the␈α∞calling␈α
style␈α∞to␈α
be␈α∞used␈α
when
␈↓ ↓H␈↓applying␈α
the␈α
definition.␈α
One␈α
way␈α
is␈α
to␈α∞revise␈α
the␈α
␈↓αisspec␈↓␈α
technique␈α
slightly:␈α
we␈α
use␈α
␈↓αlookup␈↓␈α∞for␈α
␈↓↓all␈↓
␈↓ ↓H␈↓searches,␈αbut␈αalso␈αhave␈αa␈α
table␈αrelating␈αfunction-name␈αwith␈αits␈α
calling␈αstyle.␈αOne␈αdifficulty␈αwith␈α
this
␈↓ ↓H␈↓scheme␈αis␈αthat␈αwe␈αcould␈αnot␈αhandle␈α
anonymous␈αfexpr␈αdefinitions.␈αTherefore␈αsome␈αversions␈αof␈α
LISP
␈↓ ↓H␈↓replace␈α∪the␈α∪character␈α∪"λ"␈α∪with␈α∪another␈α∪special␈α∪character␈α∪when␈α∪making␈α∪fexpr␈α∪definitions.␈α∪For
␈↓ ↓H␈↓example:
␈↓ ↓H␈↓α␈↓ ∧sg <␈↓βf␈↓α= λ[[x;y] ␈↓λx␈↓α] ␈↓≡␈↓α g <= β[[x;y] ␈↓λx␈↓α].
␈↓ ↓H␈↓We␈α∂would␈α∂translate␈α∂such␈α∂β-expressions␈α∂into␈α∂S-expr␈α∂form,␈α∂and␈α∂extend␈α∂the␈α∂evaluator␈α∂to␈α∞recognize
␈↓ ↓H␈↓such constructs.
␈↓ ↓H␈↓We␈α∞could␈α∞use␈α∂a␈α∞similar␈α∞technique␈α∂to␈α∞recognize␈α∞macro␈α∞definitions.␈α∂ The␈α∞next␈α∞chapter␈α∂will␈α∞discuss
␈↓ ↓H␈↓some alternative implementations.
␈↓ ↓H␈↓␈↓↓4.10␈↓ λ\Function Definitions 213␈↓
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Define ␈↓αlist␈↓ as a special form.
␈↓ ↓H␈↓II. Write a version of ␈↓αpeval␈↓ to handle β-expressions.
␈↓ ↓H␈↓III.␈αDefine␈αtwo␈αspecial␈αforms,␈α␈↓αde␈↓␈αand␈α␈↓αdf␈↓,␈αwhich␈αwill␈αimplement␈α<=␈αand␈α<␈↓βf␈↓=␈αrespectively.␈αThe␈αformat
␈↓ ↓H␈↓of these special forms is identical. For example:
␈↓ ↓H␈↓␈↓ ∧J␈↓αde␈↓[<name>;<formal parameters>;<body>]
␈↓ ↓H␈↓will implement
␈↓ ↓H␈↓␈↓ ∧7<name> <= λ[<formal parameters> <body>]
␈↓ ↓H␈↓␈↓ ∧←␈↓↓4.11 Rapprochement: In Retrospect␈↓
␈↓ ↓H␈↓As␈α
with␈α
the␈α
review␈α
section␈α
of␈α
the␈α
previous␈α
chapter,␈α
this␈α
section␈α
is␈α
a␈α
mixture␈α
of␈α
the␈α
practical␈αand␈α
the
␈↓ ↓H␈↓theoretical.␈α
That␈α∞is␈α
a␈α∞healthy␈α
attitude␈α
to␈α∞cultivate␈α
when␈α∞discussing␈α
programming␈α∞languages.␈α
For
␈↓ ↓H␈↓example,␈α∞in␈α∞the␈α∞first␈α
section␈α∞of␈α∞this␈α∞chapter␈α∞we␈α
claimed␈α∞that␈α∞a␈α∞theoretically␈α∞expected␈α
relationship
␈↓ ↓H␈↓between␈α∞call-by-name␈α∞and␈α
call-by-value␈α∞breaks␈α∞down␈α
in␈α∞the␈α∞presence␈α
of␈α∞side-effects.␈α∞ The␈α∞idea␈α
of
␈↓ ↓H␈↓side-effects␈α
is␈α∞a␈α
decidedly␈α
practical␈α∞one,␈α
based␈α∞on␈α
the␈α
"practical"␈α∞notion␈α
of␈α
a␈α∞"variable"␈α
as␈α∞a␈α
"box
␈↓ ↓H␈↓which␈α
contains␈α
a␈αvalue",␈α
rather␈α
than␈α
the␈αmathematical␈α
notion␈α
of␈α
a␈α"variable"␈α
as␈α
a␈α
description␈αfor
␈↓ ↓H␈↓an anonymous, but fixed, element of a domain.
␈↓ ↓H␈↓Consider the following expression:
␈↓ ↓H␈↓α␈↓ βxprog [[ ]␈↓ ∧hy ← 0;
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧hλ[[x] prog[[ ]
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧h␈↓ ¬_loop␈↓ ¬h[eq[y;0] → go[loop]]]
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧h [y ← 1]]]
␈↓ ↓H␈↓If␈α∞this␈α∂expression␈α∞is␈α∂evaluated␈α∞using␈α∞call-by-value,␈α∂we␈α∞bind␈α∂␈↓αy␈↓␈α∞to␈α∞␈↓α0␈↓,␈α∂and␈α∞evaluate␈α∂the␈α∞anonymous
␈↓ ↓H␈↓λ-expression.␈α∞That␈α∞entails␈α∞evaluation␈α∞of␈α∞␈↓αy ← 1␈↓,␈α
␈↓↓before␈↓␈α∞entering␈α∞the␈α∞␈↓αprog␈↓.␈α∞The␈α∞computation␈α∞of␈α
the
␈↓ ↓H␈↓␈↓αprog␈↓ body␈α
terminates,␈α
returning␈α∞␈↓αNIL␈↓.␈α
Call-by-name␈α
evaluation␈α
would␈α∞not␈α
evaluate␈α
␈↓αy ← 1␈↓␈α∞and␈α
the
␈↓ ↓H␈↓computation would not terminate.
␈↓ ↓H␈↓The␈α~issue␈α~of␈α~side-effects␈α~highlights␈α~an␈α~important␈α~distinction␈α~between␈α~"variables"␈α~in␈α→the
␈↓ ↓H␈↓mathematical␈α∞sense␈α∞and␈α
"variables"␈α∞in␈α∞the␈α
programming␈α∞sense.␈α∞ In␈α
mathematics,␈α∞we␈α∞use␈α∞the␈α
term,
␈↓ ↓H␈↓variable,␈αto␈αdesignate␈αa␈αfixed,␈αbut␈αanonymous,␈αobject:␈α"let␈α␈↓αx␈↓␈αbe␈αa␈αreal␈αnumber ...".␈αIn␈αprogramming
␈↓ ↓H␈↓languages,␈αan␈αobject␈αis␈α"variable"␈αas␈αopposed␈αto␈αa␈α"constant",␈αmeaning␈αthat␈αthe␈α
quantity␈αassociated
␈↓ ↓H␈↓with␈α⊃the␈α⊃object␈α⊃may␈α⊃vary.␈α∩Thus␈α⊃the␈α⊃idea␈α⊃of␈α⊃"box␈α∩which␈α⊃contains␈α⊃a␈α⊃value"␈α⊃arises␈α∩again.␈α⊃The
␈↓ ↓H␈↓manipulation of variables in languages leads to further distinctions.
␈↓ ↓H␈↓␈↓↓214 Imperative Constructs in LISP␈↓ (4.11␈↓
␈↓ ↓H␈↓Applicative␈αlanguages,␈αmodelled␈αafter␈αthe␈α␈↓λλ␈↓-calculus,␈αsimulate␈αthe␈αreduction␈αrules␈αby␈αassociating␈αan
␈↓ ↓H␈↓environment␈α
or␈α
symbol␈α
table␈α∞with␈α
an␈α
expression.␈α
What␈α
is␈α∞being␈α
simulated␈α
is␈α
a␈α∞"copy rule"␈α
which
␈↓ ↓H␈↓says␈α
that␈α
the␈α
reduction␈α
is␈α∞to␈α
be␈α
done␈α
by␈α
making␈α
a␈α∞copy␈α
of␈α
the␈α
expression,␈α
substituting␈α∞the␈α
actual
␈↓ ↓H␈↓parameters␈αinto␈αthe␈αcopy␈αwherever␈αone␈αof␈αthe␈α␈↓λλ␈↓-variables␈αappeared␈αin␈αthe␈αoriginal␈αexpression.␈αThe
␈↓ ↓H␈↓effect␈α∂of␈α∂the␈α⊂symbol␈α∂table␈α∂is␈α⊂to␈α∂␈↓↓share␈↓␈α∂a␈α∂common␈α⊂instance␈α∂of␈α∂the␈α⊂actual␈α∂parameter.␈α∂The␈α⊂idea␈α∂of
␈↓ ↓H␈↓sharing␈αbecomes␈α
central␈αwhen␈αwe␈α
discuss␈αassignments␈αand␈α
the␈αbehavior␈αof␈α
side-effects.␈α If␈α␈↓↓copies␈↓␈α
of
␈↓ ↓H␈↓values␈α
are␈αmade,␈α
the␈α
issue␈αof␈α
side-effects␈α
vanishes.␈α Important␈α
distinctions␈α
arise␈αwhen␈α
we␈α
are␈αable
␈↓ ↓H␈↓both␈αto␈α␈↓↓share␈↓␈αvalues␈αand␈αto␈αdestructively␈α␈↓↓change␈↓␈αvalues.␈αThis␈αcombination␈αof␈αproperties␈αis␈αpresent
␈↓ ↓H␈↓in␈α⊂the␈α∂general␈α⊂assignment␈α∂statement.␈α⊂ Because␈α∂of␈α⊂the␈α∂close␈α⊂relationship␈α∂between␈α⊂assignment␈α∂and
␈↓ ↓H␈↓LISP's␈αλ-binding,␈αλ-binding␈αis␈αsometimes␈αcalled␈αa␈α"pushdown"␈αassignment␈α([New 61]),␈αas␈αcompared
␈↓ ↓H␈↓with␈α∂a␈α⊂"destructive"␈α∂assignment.␈α⊂ The␈α∂adjective,␈α∂"pushdown",␈α⊂refers␈α∂to␈α⊂the␈α∂λ-binding's␈α⊂ability␈α∂to
␈↓ ↓H␈↓save␈αthe␈αprior␈αbinding␈αof␈αa␈αλ-variable␈αin␈αsuch␈αa␈αway␈αthat␈αit␈αmay␈αbe␈αrestored␈αafter␈αthe␈αcomputation
␈↓ ↓H␈↓is completed.
␈↓ ↓H␈↓Differences␈α⊃in␈α∩binding␈α⊃are␈α∩highlighted␈α⊃by␈α⊃the␈α∩implementation␈α⊃of␈α∩␈↓αfunction␈↓.␈α⊃ In␈α∩the␈α⊃applicative
␈↓ ↓H␈↓subset,␈α⊂␈↓αfunction␈↓␈α⊃is␈α⊂satisfactorily␈α⊂implemented␈α⊃by␈α⊂the␈α⊂␈↓αFUNARG␈↓␈α⊃triple,␈α⊂where␈α⊂the␈α⊃substitution␈α⊂is
␈↓ ↓H␈↓represented␈αby␈αa␈α
pointer␈αto␈αthe␈αbinding␈α
environment.␈αIn␈αthe␈α
presence␈αof␈αassignment␈αstatements,␈α
this
␈↓ ↓H␈↓equivalence breaks down.
␈↓ ↓H␈↓Consider the following example due to H. Samet:
␈↓ ↓H␈↓␈↓ βx␈↓αf <= λ[[x] prog␈↓ ¬X[[]
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬X a ← a+1;
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬X return[[eq[a;1] → x; ␈↓
t␈↓α → -x]]]]
␈↓ ↓H␈↓␈↓ βx␈↓αg <= λ[[x;fun] prog␈↓ ε_[[]
␈↓ ↓H␈↓α␈↓ βx␈↓ ε_ a ␈↓ ε> 0;
␈↓ ↓H␈↓α␈↓ βx␈↓ ε_ return[fun[x]]]]
␈↓ ↓H␈↓␈↓αh <= λ[[a] g[3;function[f]]].
␈↓ ↓H␈↓Now evaluate: ␈↓αh[1]␈↓.
␈↓ ↓H␈↓If␈α∞we␈α∞implemented␈α∞␈↓αfunction␈↓␈α∞as␈α∞a␈α∞direct␈α∞substitution␈α∞of␈α∞values␈α∞for␈α∞free␈α∞variables,␈α∞then␈α∞␈↓αh[1]␈↓␈α
would
␈↓ ↓H␈↓yield␈α
␈↓α-3␈↓.␈α The␈α
implementation␈αof␈α
␈↓αfunction␈↓␈αas␈α
a␈α
pointer␈αto␈α
the␈αbinding␈α
environment␈αyields␈α
␈↓α3␈↓.␈α
It␈αis
␈↓ ↓H␈↓clear␈αwhere␈αthe␈αproblem␈αlies;␈αwe␈αhave␈αassigned␈αto␈αa␈αnon-local␈αvariable␈αafter␈αthe␈αsubstitution␈αwould
␈↓ ↓H␈↓have␈α∂been␈α∂carried␈α∂out.␈α∂ However,␈α∂compare␈α∂the␈α∂current␈α∂situation␈α∂with␈α∂the␈α∂example␈α⊂on␈α∂page 131.
␈↓ ↓H␈↓The lesson to be learned is that assignment statements do not fit well with the substitution model.
␈↓ ↓H␈↓We␈α
had␈α
enriched␈α
the␈αLISP␈α
subset␈α
to␈α
allow␈α
such␈αconstructs␈α
as␈α
iteration␈α
and␈α
assignment;␈αtherefore,
␈↓ ↓H␈↓we␈α
wished␈α
to␈α
provide␈α
an␈α
evaluator␈α
which␈α
adequately␈α
reflected␈α
the␈α
implementation,␈α
or␈αpragmatics,
␈↓ ↓H␈↓of␈α∩these␈α∩facilities.␈α∩We␈α∩could␈α∩have␈α∩modelled␈α⊃them␈α∩directly␈α∩in␈α∩the␈α∩initial␈α∩LISP␈α∩subset,␈α∩but␈α⊃the
␈↓ ↓H␈↓representation␈α∪would␈α∪not␈α∪convey␈α∪the␈α∪intended␈α∪implementation.␈α∪As␈α∪a␈α∪result,␈α∪we␈α∪developed␈α∪an
␈↓ ↓H␈↓interpreter␈α⊂which␈α⊂can␈α∂directly␈α⊂model␈α⊂the␈α∂effect␈α⊂of␈α⊂assignment␈α∂statements,␈α⊂␈↓αreturn␈↓␈α⊂statements,␈α∂and
␈↓ ↓H␈↓non-local␈α
␈↓αgo␈↓␈α∞statements;␈α
these␈α∞are␈α
some␈α∞of␈α
the␈α∞most␈α
troublesome␈α∞areas␈α
to␈α∞reflect␈α
in␈α∞an␈α
applicative
␈↓ ↓H␈↓model.
␈↓ ↓H␈↓The␈α⊂result␈α⊂of␈α⊂our␈α⊃investigations␈α⊂was␈α⊂the␈α⊂evaluator␈α⊂␈↓αpeval␈↓.␈α⊃This␈α⊂evaluator␈α⊂plays␈α⊂the␈α⊂role␈α⊃of␈α⊂the
␈↓ ↓H␈↓␈↓↓4.11␈↓ π[Rapprochement: In Retrospect 215␈↓
␈↓ ↓H␈↓evaluators␈αof␈αthe␈αprevious␈αchapter;␈αit␈αexpresses␈αthe␈αimplementation␈αof␈αthe␈αenriched␈αsubset␈αof␈αLISP;
␈↓ ↓H␈↓it␈α∪is␈α∪self-explanatory␈α∪in␈α∪the␈α∪sense␈α∪that␈α∀any␈α∪construct␈α∪which␈α∪␈↓αpeval␈↓␈α∪uses␈α∪has␈α∪a␈α∀data␈α∪structure
␈↓ ↓H␈↓representation␈α
which␈α
is␈α
recognizable␈α
by␈α∞␈↓αpeval␈↓.␈α
That␈α
is,␈α
␈↓αpeval␈↓␈α
can␈α
interpret␈α∞expressions␈α
involving
␈↓ ↓H␈↓representations of ␈↓αpeval␈↓.
␈↓ ↓H␈↓The␈αprocess␈αof␈αdeveloping␈α␈↓αpeval␈↓␈αexposed␈αthe␈αcontrol␈αstructure␈αof␈αLISP␈αjust␈αas␈αthe␈αdevelopment␈αof
␈↓ ↓H␈↓␈↓αeval␈↓␈α⊃in␈α⊂Chapter 3␈α⊃exposed␈α⊂the␈α⊃access␈α⊃structure.␈α⊂Chapter 3␈α⊃developed␈α⊂data␈α⊃structure␈α⊃models␈α⊂for
␈↓ ↓H␈↓access␈α⊗environments;␈α⊗this␈α⊗was␈α⊗necessary␈α⊗since␈α⊗the␈α⊗implementation␈α⊗of␈α⊗␈↓αfunction␈↓␈α⊗demanded␈α∃it.
␈↓ ↓H␈↓Traditional␈αLISP␈αdoes␈αnot␈αallow␈αsuch␈αgenerality␈αin␈αthe␈αarea␈αof␈αcontrol␈αstructure.␈α
The␈αappearance
␈↓ ↓H␈↓of␈α⊃non-local␈α⊃␈↓αgo␈↓s␈α⊃and␈α⊃␈↓αreturn␈↓s␈α⊃requires␈α⊃control␈α⊃behavior␈α⊃analogous␈α⊃to␈α⊃functional␈α⊃arguments,␈α⊂but
␈↓ ↓H␈↓control␈α∂regimes␈α∂analogous␈α∞to␈α∂functional␈α∂␈↓↓values␈↓␈α∞do␈α∂not␈α∂appear.␈α∞More␈α∂recent␈α∂demands␈α∂from␈α∞LISP
␈↓ ↓H␈↓users␈α↔have␈α⊗prompted␈α↔development␈α⊗of␈α↔generalized␈α⊗control␈α↔structures␈α⊗in␈α↔LISP-like␈α⊗languages
␈↓ ↓H␈↓([Hew 72],␈α∃[Pre 72],␈α∀[Pre 76a],␈α∃[Bob 73a],␈α∃[Con 73]).␈α∀Now␈α∃that␈α∃we␈α∀have␈α∃developed␈α∃the␈α∀data
␈↓ ↓H␈↓structure␈α∀representation␈α∀for␈α∪control,␈α∀we␈α∀could␈α∪extend␈α∀LISP␈α∀to␈α∪allow␈α∀manipulation␈α∀of␈α∪control
␈↓ ↓H␈↓structures. We resist that temptation, leaving such experimentation to the reader.
␈↓ ↓H␈↓As␈α∞we␈α∞have␈α∞just␈α∞seen␈α∞there␈α∞are␈α∂alternatives␈α∞to␈α∞some␈α∞of␈α∞the␈α∞LISP-techniques␈α∞and␈α∞there␈α∂are␈α∞some
␈↓ ↓H␈↓things␈α
which,␈α∞in␈α
retrospect,␈α
LISP␈α∞could␈α
have␈α∞done␈α
better.␈α
There␈α∞are␈α
some␈α∞conceptual␈α
difficulties
␈↓ ↓H␈↓with␈α∞LISP␈α∞evaluation.␈α∞ We␈α∞have␈α∞seen␈α∂some␈α∞computational␈α∞schemes␈α∞which␈α∞will␈α∞give␈α∂values␈α∞when
␈↓ ↓H␈↓LISP's␈α∂call-by-value␈α∞does␈α∂not␈α∂terminate.␈α∞ Whether␈α∂these␈α∞schemes␈α∂are␈α∂better␈α∞is␈α∂a␈α∂debatable␈α∞point.
␈↓ ↓H␈↓Programmers␈α
tend␈αto␈α
think␈α
"call-by-value",␈αbut␈α
it␈α
is␈αnot␈α
clear␈αwhether␈α
that␈α
is␈αhabit,␈α
training,␈α
or␈αa
␈↓ ↓H␈↓fundamental point of view towards computation␈↓π 142␈↓.
␈↓ ↓H␈↓The␈αpractical␈α
and␈αthe␈α
theoretical␈αaspects␈αof␈α
programming␈αlanguages␈α
have␈αseveral␈αcommon␈α
interests.
␈↓ ↓H␈↓As␈α∞we␈α∞have␈α∞seen,␈α∞the␈α
notion␈α∞of␈α∞"function"␈α∞in␈α∞mathematics␈α
is␈α∞different␈α∞from␈α∞the␈α∞notion␈α∞of␈α
"LISP
␈↓ ↓H␈↓function".␈α∩The␈α∪former␈α∩is␈α∩a␈α∪set-theoretic␈α∩notion,␈α∩the␈α∪latter␈α∩is␈α∩an␈α∪algorithmic␈α∩notion.␈α∪With␈α∩the
␈↓ ↓H␈↓introduction␈α⊗of␈α↔iteration,␈α⊗a␈α⊗further␈α↔discrimination␈α⊗is␈α⊗useful.␈α↔This␈α⊗requires␈α⊗a␈α↔discussion␈α⊗of
␈↓ ↓H␈↓"recursive". A useful classification appears in [Hew 76].
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 142␈↓␈α⊃Compare␈α∩[And 76]␈α⊃in␈α∩discussing␈α⊃call-by-name␈α⊃versus␈α∩call-by-value:␈α⊃"programs␈α∩which␈α⊃don't
␈↓ ↓H␈↓terminate␈α∞usually␈α
have␈α∞bugs,␈α
and␈α∞programmers␈α∞would␈α
rather␈α∞find␈α
out␈α∞sooner␈α∞(call-by-value)␈α
than
␈↓ ↓H␈↓later (call-by-name)".
␈↓ ↓H␈↓␈↓↓216 Imperative Constructs in LISP␈↓ (4.11␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓␈α∪"Recursive"␈α∩in␈α∪the␈α∩sense␈α∪of␈α∪recursive␈α∩function␈α∪theory␈α∩([Rog 67])␈α∪meaning␈α∩that␈α∪there␈α∪is␈α∩an
␈↓ ↓H␈↓␈↓ ↓xalgorithm␈α∩which␈α∪specifies␈α∩the␈α∪function.␈α∩ This␈α∪involves␈α∩a␈α∪precise␈α∩study␈α∪of␈α∩the␈α∪concepts␈α∩of
␈↓ ↓H␈↓␈↓ ↓xalgorithm and computability.
␈↓ ↓H␈↓␈↓↓2.␈↓␈α"Recursive"␈α
in␈αthe␈α
sense␈αof␈α
self-referential.␈αThe␈α
definition␈αof␈α
an␈αalgorithm␈α
makes␈αreference␈αto␈α
the
␈↓ ↓H␈↓␈↓ ↓xalgorithm␈α
itself.␈α
The␈α
idea␈αof␈α
"self-reference"␈α
needs␈α
to␈αbe␈α
handled␈α
carefully.␈α
The␈αdefinition␈α
may
␈↓ ↓H␈↓␈↓ ↓xinvolve␈αmutual␈αrecursion:␈α␈↓αf␈↓␈αcalls␈α␈↓αg␈↓,␈α
and␈α␈↓αg␈↓␈αcalls␈α␈↓αf␈↓.␈αAlso,␈αwe␈α
saw␈αon␈αpage 135␈αthat␈αa␈αfunction␈α
may
␈↓ ↓H␈↓␈↓ ↓xbe dynamically self-referential, while the static text is not.
␈↓ ↓H␈↓␈↓↓3.␈↓␈αFinally,␈α"recursive"␈αis␈αused␈αmeaning␈α"non-iterative".␈α This␈αis␈αthe␈αusual␈αinterpretation␈αimposed␈αin
␈↓ ↓H␈↓␈↓ ↓xprogramming␈α≠languages.␈α≤ This␈α≠sense␈α≤implies␈α≠some␈α≤assumptions␈α≠about␈α≤the␈α≠evaluation
␈↓ ↓H␈↓␈↓ ↓ximplementation.␈α⊗ Basically,␈α⊗it␈α⊗is␈α⊗to␈α⊗mean␈α∃that␈α⊗a␈α⊗recursive␈α⊗evaluation␈α⊗will␈α⊗require␈α∃more
␈↓ ↓H␈↓␈↓ ↓xbookkeeping␈α∩than␈α∩the␈α∩iterative␈α∩evaluation.␈α∩A␈α⊃problem␈α∩on␈α∩page 179␈α∩asked␈α∩for␈α∩an␈α⊃iterative
␈↓ ↓H␈↓␈↓ ↓xevaluation␈α∃of␈α⊗␈↓αfact[2]␈↓;␈α∃fewer␈α∃environments␈α⊗were␈α∃created␈α∃there␈α⊗than␈α∃we␈α∃required␈α⊗for␈α∃the
␈↓ ↓H␈↓␈↓ ↓xevaluation␈αof␈αthe␈α"recursive"␈α(in␈αthe␈αsense␈αof␈α
␈↓↓2␈↓)␈αversion.␈α This␈αthird␈αuse␈αof␈αthe␈αword␈α
"recursive"
␈↓ ↓H␈↓␈↓ ↓xis␈αthe␈αleast␈αwell␈αdefined␈αand␈αunderstood.␈α It␈αis␈αfrequently␈αbelieved␈αthat␈α"recursive"␈αin␈αthe␈αsense
␈↓ ↓H␈↓␈↓ ↓xof␈α␈↓↓2␈↓␈αimplies␈αthe␈αthird␈α"recursive".␈αThe␈αthird␈αsense␈αis␈αmore␈αa␈αproperty␈αof␈αthe␈αimplementation␈αof
␈↓ ↓H␈↓␈↓ ↓xthe␈αevaluation␈αscheme␈α
than␈αa␈αproperty␈α
of␈αthe␈αalgorithm.␈α
Techniques␈αare␈αknow␈α
for␈αevaluating
␈↓ ↓H␈↓␈↓ ↓xseveral␈α
classes␈αof␈α
"recursive"␈αalgorithms␈α
using␈α
iterative␈αstorage␈α
requirements;␈α[Hew 76],␈α
[Sus 76],
␈↓ ↓H␈↓␈↓ ↓x[Gre 76a].
␈↓ ↓H␈↓Since␈α
the␈α
ideas␈α
involved␈α∞in␈α
"recursive"␈α
are␈α
so␈α
important␈α∞to␈α
LISP␈α
and␈α
programming␈α∞languages␈α
in
␈↓ ↓H␈↓general,␈αwe␈αwant␈αto␈αexplore␈αthe␈αideas␈αfurther.␈α We␈αwill␈αbe␈αmost␈αconcerned␈αwith␈α"recursive"␈αin␈αsense
␈↓ ↓H␈↓␈↓↓2␈↓;␈α
we␈α
want␈α
to␈α
understand␈α
what␈α
is␈α
involved␈α
in␈α
giving␈α
a␈α
recursive␈α
definition.␈α
We␈α
now␈α∞have␈α
three
␈↓ ↓H␈↓ways␈α∞to␈α∞define␈α
functions:␈α∞the␈α∞␈↓αlabel␈↓␈α
operator,␈α∞the␈α∞"<=" operator,␈α
and␈α∞the␈α∞assignment␈α∞statement.␈α
We
␈↓ ↓H␈↓need to understand the differences between these operations.
␈↓ ↓H␈↓To begin with, we were able to give counterexamples to interpreting:
␈↓ ↓H␈↓␈↓ ∧␈␈↓αf <= λ[[x] ␈↓λx␈↓] as ␈↓αf ← λ[[x] ␈↓λx␈↓α].
␈↓ ↓H␈↓The␈α
discussion␈α
of␈α∞binding␈α
and␈α
environments␈α
made␈α∞␈↓αf ← function[λ[[x] ␈↓λx␈↓α]]␈↓␈α
a␈α
more␈α∞likely␈α
candidate;
␈↓ ↓H␈↓however this interpretation is also not adequate.
␈↓ ↓H␈↓We attempt to implement ␈↓ ∧5␈↓αfact <= λ[[x][x=0 → 1; ␈↓
t␈↓α → *[x;fact[x-1]]]]␈↓ as:
␈↓ ↓H␈↓α␈↓ ∧rfact ← function[λ[[x] ... fact[x-1] ...]
␈↓ ↓H␈↓Consider an initial environment with ␈↓αfact␈↓ defined:
␈↓ ↓H␈↓␈↓ ¬_␈↓ ¬XE␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_E␈↓βc␈↓␈↓ ¬X|␈↓ ε_E␈↓βa␈↓
␈↓ ↓H␈↓␈↓ ¬____________
␈↓ ↓H␈↓␈↓ ¬_␈↓αfact␈↓␈↓ ¬X| ␈↓αλ[[x] ...fact[x-1]] ␈↓: E␈↓βi␈↓
␈↓ ↓H␈↓␈↓↓4.11␈↓ π[Rapprochement: In Retrospect 217␈↓
␈↓ ↓H␈↓We␈α∪will␈α∩demonstrate␈α∪the␈α∩inadequacy␈α∪of␈α∩two␈α∪natural␈α∩interpretations␈α∪of␈α∩function␈α∪values:␈α∩direct
␈↓ ↓H␈↓assignment␈α∞of␈α
value,␈α∞and␈α∞assignment␈α
of␈α∞␈↓αfunarg␈↓.␈α
We␈α∞execute␈α∞␈↓αfoo␈α
←␈α∞fact␈↓␈α
and␈α∞␈↓αbaz␈α∞←␈α
function[fact]␈↓,
␈↓ ↓H␈↓giving:
␈↓ ↓H␈↓␈↓ ¬_␈↓ ¬XE␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_E␈↓βc␈↓␈↓ ¬X|␈↓ ε_E␈↓βa␈↓
␈↓ ↓H␈↓␈↓ ¬____________
␈↓ ↓H␈↓␈↓ ¬_␈↓αfact␈↓␈↓ ¬X| ␈↓αλ[[x] ...fact[x-1]] ␈↓: E␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_␈↓αfoo␈↓␈↓ ¬X| ␈↓αλ[[x] ...fact[x-1]] ␈↓: E␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_␈↓αbaz␈↓␈↓ ¬X| ␈↓αfact ␈↓: E␈↓βi␈↓
␈↓ ↓H␈↓Things␈αdon't␈αlook␈αquite␈αright;␈αthe␈α"intent"␈αof␈αboth␈α␈↓αfoo ← fact␈↓␈αand␈α␈↓αbaz ← function[fact]␈↓␈αwas␈αto␈αmake
␈↓ ↓H␈↓␈↓αfoo␈↓␈α
and␈α
␈↓αbaz␈↓␈α
synonymous␈α
with␈α
␈↓αfact␈↓.␈α
That␈α
clearly␈α
is␈α
not␈α
the␈α
case␈α
though␈α
the␈α
right␈α
thing␈α
happens␈αif␈α
we
␈↓ ↓H␈↓were␈α
now␈α
to␈α
evaluate␈α
an␈αexpression␈α
involving␈α
␈↓αfoo␈↓␈α
or␈α
␈↓αbaz␈↓.␈α
The␈αproblem␈α
is␈α
that␈α
it␈α
happens␈α
for␈αthe
␈↓ ↓H␈↓wrong␈α
reason␈αeven␈α
though␈α
the␈αoccurrence␈α
of␈α
␈↓αfact␈↓␈αin␈α
the␈α
body␈αof␈α
␈↓αfoo␈↓␈α
will␈αfind␈α
the␈α
right␈αdefinition␈α
of
␈↓ ↓H␈↓␈↓αfact␈↓; an application of ␈↓αbaz␈↓ will find the definition of ␈↓αfact␈↓.
␈↓ ↓H␈↓One more step will lead to disaster: ␈↓αfact ← λ[[x] x]␈↓.
␈↓ ↓H␈↓␈↓ ¬_␈↓ ¬XE␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_E␈↓βc␈↓␈↓ ¬X|␈↓ ε_E␈↓βa␈↓
␈↓ ↓H␈↓␈↓ ¬____________
␈↓ ↓H␈↓␈↓ ¬_␈↓αfact␈↓␈↓ ¬X| ␈↓αλ[[x]x]
␈↓ ↓H␈↓α␈↓ ¬_foo␈↓ ¬X| λ[[x] ...fact[x-1]] ␈↓: E␈↓βi␈↓
␈↓ ↓H␈↓␈↓ ¬_␈↓αbaz␈↓␈↓ ¬X| ␈↓αfact ␈↓: E␈↓βi␈↓
␈↓ ↓H␈↓Now␈αwe␈αare␈αreally␈αlost.␈αThough␈αit␈αis␈αperfectly␈αreasonable␈αto␈αredefine␈α␈↓αfact␈↓␈α-- it␈αis␈αonly␈αa␈αname --␈αour
␈↓ ↓H␈↓intent␈α∞was␈α
to␈α∞keep␈α
␈↓αbaz␈↓␈α∞and␈α
␈↓αfoo␈↓␈α∞as␈α
realizations␈α∞of␈α
the␈α∞factorial␈α
function.␈α∞This␈α
intent␈α∞has␈α∞not␈α
been
␈↓ ↓H␈↓maintained.
␈↓ ↓H␈↓␈↓ ∧ ␈↓αfact␈↓ <= ␈↓αλ[[x] ...fact[x-1]]␈↓ is quite different from:
␈↓ ↓H␈↓␈↓ ¬~␈↓αfoo␈↓ <= ␈↓αλ[[x] ...fact[x-1]]. ␈↓π 143␈↓α
␈↓ ↓H␈↓To␈α∀understand␈α∀what␈α∀is␈α∀happening␈α∀we␈α∀look␈α∀at␈α∀assignments␈α∀to␈α∀␈↓↓simple␈↓␈α∀variables␈α∀rather␈α∀than
␈↓ ↓H␈↓functional␈α∞variables.␈α∞It␈α∞is␈α∞clear␈α∞how␈α∞the␈α∞environment␈α∞should␈α∞change␈α∞during␈α∞the␈α∞execution␈α∞of␈α
the
␈↓ ↓H␈↓sequence:
␈↓ ↓H␈↓α␈↓ ¬_x ← 3
␈↓ ↓H␈↓α␈↓ ¬_y ← x
␈↓ ↓H␈↓α␈↓ ¬_x ← 4
␈↓ ↓H␈↓Let's try something slightly more complicated:
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓α␈↓π 143␈↓α␈αIn␈αLISP␈α1␈α
([McC 60])␈αconsiderations␈αwere␈αgiven␈α
to␈αrepresenting␈αrecursive␈αdefinitions␈αas␈α
circular
␈↓ ↓H␈↓αstructure, instead of referring to the name. That would have solved the current problem.
␈↓ ↓H␈↓␈↓↓218 Imperative Constructs in LISP␈↓ (4.11␈↓
␈↓ ↓H␈↓α␈↓ ¬_x ← 1
␈↓ ↓H␈↓α␈↓ ¬_x ← x␈↓π2␈↓α - 6
␈↓ ↓H␈↓Here␈α⊃we␈α⊃simply␈α⊃assign␈α⊃␈↓α1␈↓␈α⊃to␈α⊃␈↓αx␈↓;␈α⊃then␈α⊃while␈α⊂we␈α⊃are␈α⊃evaluating␈α⊃the␈α⊃right␈α⊃hand␈α⊃side␈α⊃of␈α⊃the␈α⊂next
␈↓ ↓H␈↓statement,␈α∞we␈α∞look␈α∞up␈α∞the␈α∞current␈α∞value␈α∞of␈α∞␈↓αx␈↓,␈α∞perform␈α∞the␈α∞appropriate␈α∞computations,␈α∂and␈α∞finally
␈↓ ↓H␈↓assign␈α⊃the␈α⊃value␈α⊃␈↓α-5␈↓␈α⊃to␈α⊃␈↓αx␈↓.␈α⊃Compare␈α⊃␈↓↓this␈↓␈α∩to␈α⊃the␈α⊃␈↓αfact␈↓␈α⊃definition;␈α⊃there␈α⊃we␈α⊃made␈α⊃a␈α⊃point␈α∩of␈α⊃not
␈↓ ↓H␈↓"evaluating" the name ␈↓αfact␈↓ in the right hand side of "<=".
␈↓ ↓H␈↓Notice␈α⊂that␈α⊂␈↓↓after␈↓␈α∂an␈α⊂assignment␈α⊂like␈α⊂␈↓αy ← x␈↓␈α∂has␈α⊂been␈α⊂executed,␈α∂then␈α⊂equality␈α⊂holds␈α⊂between␈α∂the
␈↓ ↓H␈↓left-hand␈α∞and␈α∞right-hand␈α∞quantities.␈α∞ Let's␈α∞look␈α∞more␈α∞closely␈α∞at␈α∞the␈α∞relationship␈α∞between␈α∞"←"␈α∞and
␈↓ ↓H␈↓"=".␈α
Consider␈α
␈↓αx ← x␈↓π2␈↓α - 6␈↓.␈α
After␈α∞the␈α
assignment␈α
is␈α
made,␈α
equality␈α∞does␈α
␈↓↓not␈↓␈α
hold␈α
between␈α∞left-␈α
and
␈↓ ↓H␈↓right-hand␈αsides.␈α Now␈α
consider␈α␈↓αx = x␈↓π2␈↓α - 6␈↓.␈α Interpreting␈α
this␈αexpression␈αas␈α
an␈αequation,␈αnot␈α
as␈αan
␈↓ ↓H␈↓expression␈αwhose␈αvalue␈αis␈αtrue␈αor␈αfalse␈αdepending␈αon␈αthe␈αcurrent␈αvalue␈αof␈α␈↓αx␈↓,␈αwe␈αfind␈αtwo␈αsolutions:
␈↓ ↓H␈↓let␈α␈↓αx␈↓␈αhave␈αvalue␈α␈↓α-2␈↓␈αor␈α␈↓α3␈↓.␈α If␈αwe␈αexamine␈αour␈α"definition"␈αof␈α␈↓αfact␈↓␈αin␈α␈↓↓this␈↓␈αlight,␈αinterpreting␈α"<="␈αas
␈↓ ↓H␈↓being␈αrelated␈αto␈α
"="␈αrather␈αthan␈α"←",␈α
then␈αwe␈αare␈αfaced␈α
with␈αan␈αequation␈αto␈α
be␈αsolved,␈αonly␈αnow␈α
the
␈↓ ↓H␈↓form␈α∪of␈α∩the␈α∪solution␈α∩is␈α∪a␈α∪␈↓↓function␈↓␈α∩which␈α∪satisfies␈α∩the␈α∪equation.␈α∩There␈α∪are␈α∪frequently␈α∩many
␈↓ ↓H␈↓solutions;␈α
there␈α
may␈αbe␈α
no␈α
solutions.␈α In␈α
our␈α
case␈α
there␈αis␈α
at␈α
least␈αone␈α
solution:␈α
the␈α
usual␈αfactorial
␈↓ ↓H␈↓function. So what we ␈↓↓should␈↓ write is something more like:
␈↓ ↓H␈↓α␈↓ β_fact ← ␈↓a solution to the equation␈↓α: f = λ[[x][x=0 → 1; ␈↓
t␈↓α → *[x;f[x-1]]]].
␈↓ ↓H␈↓That␈α∞is,␈α∞the␈α∞␈↓↓real␈↓␈α∞intent␈α∞of␈α∞the␈α∞recursive␈α∂definition␈α∞of␈α∞␈↓αfact␈↓␈α∞was␈α∞to␈α∞define␈α∞a␈α∞function␈α∞to␈α∂effect␈α∞the
␈↓ ↓H␈↓computation␈α∞of␈α
factorial␈α∞and␈α∞then␈α
to␈α∞␈↓↓name␈↓␈α∞that␈α
function␈α∞␈↓αfact␈↓.␈α∞Questions␈α
of␈α∞when␈α∞solutions␈α
exist,
␈↓ ↓H␈↓how many, and which are the "best" solutions is a topic of much current research ([Man 74]).
␈↓ ↓H␈↓We␈α∃have␈α∀seen␈α∃a␈α∀related␈α∃result␈α∀in␈α∃the␈α∀problem␈α∃on␈α∀page 168,␈α∃where␈α∀we␈α∃were␈α∀to␈α∃show␈α∀that
␈↓ ↓H␈↓␈↓αfact = ␈↓εt␈↓α[fact]␈↓.␈α That␈αis,␈α␈↓αfact␈↓␈αis␈αa␈αsolution␈αto␈αthe␈αequation␈α␈↓εt␈↓α[x] = x␈↓.␈α Solutions␈αto␈αsuch␈αequations␈αare
␈↓ ↓H␈↓called ␈↓↓fixed points␈↓.
␈↓ ↓H␈↓The ␈↓αfact␈↓ result is an instance of a more general result:
␈↓ ↓H␈↓␈↓ βxfor any ␈↓εt␈↓, define ␈↓αh <= λ[[g] ␈↓εt␈↓α[function[λ[[x] g[g[x]]]]]␈↓
␈↓ ↓H␈↓(␈↓Y␈↓)
␈↓ ↓H␈↓␈↓ βxthen ␈↓αh[function[h]] = ␈↓εt␈↓α[h[function[h]]]␈↓.
␈↓ ↓H␈↓We␈αshall␈αnot␈αprove␈αthis␈αresult␈αbut␈αwe␈αcan␈αgive␈αsome␈αinsight␈αinto␈αits␈αjustification␈αas␈αwe␈αdevelop␈αthe
␈↓ ↓H␈↓mathematical␈α
properties␈α
of␈α
␈↓αlabel␈↓;␈α
we␈α
continue␈α
our␈α
discussion␈α
of␈α
Section 3.13.␈α
Recall␈α
␈↓εD␈↓βe␈↓␈α
and␈α␈↓εD␈↓βa␈↓␈α
from
␈↓ ↓H␈↓page 218.␈α In␈αany␈αenvironment␈α␈↓λD␈↓βa␈↓␈αshould␈αmap␈α␈↓αlabel[f;g]␈↓␈αin␈αsuch␈αa␈αway␈αthat␈αthe␈αdenotation␈αof␈α
␈↓αf␈↓␈αis
␈↓ ↓H␈↓synonymous␈α#with␈α"that␈α#of␈α#␈↓αg␈↓.␈α" That␈α#is,␈α"␈↓f␈↓␈α#is␈α#a␈α"mapping␈α#satisfying␈α#the␈α"equation
␈↓ ↓H␈↓␈↓f(t␈↓β1␈↓, ..., t␈↓βn␈↓) = g(t␈↓β1␈↓, ..., t␈↓βn␈↓)␈↓. So:
␈↓ ↓H␈↓␈↓ ∧⎇␈↓λD␈↓βa␈↓∞(␈↓αlabel[␈↓ f␈↓;␈↓ g␈↓]␈↓∞)␈↓(l)␈↓ = ␈↓λD␈↓βa␈↓∞(␈↓ g␈↓∞)␈↓(l)␈↓.
␈↓ ↓H␈↓␈↓↓4.11␈↓ π[Rapprochement: In Retrospect 219␈↓
␈↓ ↓H␈↓This␈αwill␈αsuffice␈αfor␈αour␈αcurrent␈αλ-definitions;␈αwe␈αneed␈αnot␈αmodify␈α␈↓l␈↓␈αsince␈αthe␈αname␈α␈↓αf␈↓␈αwill␈αnever␈αbe
␈↓ ↓H␈↓used within the evaluation of an expression involving ␈↓αg␈↓.
␈↓ ↓H␈↓We␈α∂must␈α⊂be␈α∂a␈α⊂bit␈α∂careful.␈α⊂ Our␈α∂treatment␈α∂of␈α⊂non-local␈α∂variables␈α⊂in␈α∂LISP␈α⊂(on␈α∂page 112␈α⊂and␈α∂in
␈↓ ↓H␈↓Section 3.8)␈α
requires␈α
that␈αthese␈α
variables␈α
be␈αevaluated␈α
when␈α
the␈αfunction␈α
is␈α
␈↓↓activated␈↓␈α
rather␈αthan
␈↓ ↓H␈↓when␈α
the␈α
function␈α
is␈α
defined.␈α
Thus␈α
a␈αλ-definition␈α
generally␈α
requires␈α
an␈α
environment␈α
in␈α
which␈αto
␈↓ ↓H␈↓evaluate␈α⊂its␈α⊂non-local␈α⊃variables.␈α⊂ So␈α⊂its␈α⊂denotation␈α⊃should␈α⊂be␈α⊂a␈α⊂mapping␈α⊃like:␈α⊂␈↓env␈↓ → ␈↓[␈↓ S␈↓πn␈↓ → ␈↓ S␈↓]␈↓
␈↓ ↓H␈↓rather␈α∪than␈α∪simply␈α∪␈↓[␈↓ S␈↓πn␈↓ → ␈↓ S␈↓]␈↓.␈α∪This␈α∪is␈α∪consistent␈α∪with␈α∪our␈α∪understanding␈α∪of␈α∪the␈α∪meaning␈α∪of
␈↓ ↓H␈↓λ-notation.␈α
It␈α
is␈α
what␈α␈↓αfunction␈↓␈α
was␈α
attempting␈α
to␈α
describe.␈αWhat␈α
we␈α
previously␈α
have␈α
called␈αan␈α
open
␈↓ ↓H␈↓function␈αis␈αof␈αthe␈αform:␈α␈↓[␈↓ S␈↓πn␈↓ → ␈↓ S␈↓]␈↓.␈α Given␈αa␈αname␈αfor␈αa␈αfunction␈αin␈αan␈αenvironment␈αwe␈αcan␈α
expect
␈↓ ↓H␈↓to receive a mapping from ␈↓env␈↓ to an element of ␈↓ Fn␈↓.
␈↓ ↓H␈↓A modification of our handling of ␈↓αlabel␈↓ is required to describe the case for recursion:
␈↓ ↓H␈↓␈↓ ∧≤␈↓λD␈↓βa␈↓∞(␈↓αlabel[␈↓ f␈↓;␈↓ g␈↓]␈↓∞)␈↓(l)␈↓ = ␈↓λD␈↓βa␈↓∞(␈↓ g␈↓∞)␈↓(l : <f,␈↓λD␈↓βa␈↓∞(␈↓ g␈↓∞)␈↓>)␈↓.
␈↓ ↓H␈↓Interpreting␈α↔this␈α↔equation␈α↔operationally,␈α⊗it␈α↔says:␈α↔when␈α↔we␈α⊗apply␈α↔a␈α↔␈↓αlabel␈↓␈α↔expression␈α↔in␈α⊗an
␈↓ ↓H␈↓environment␈αit␈α
is␈αthe␈α
same␈αas␈α
applying␈αthe␈αbody␈α
of␈αthe␈α
definition␈αin␈α
an␈αenvironment␈α
modified␈αto
␈↓ ↓H␈↓associate␈αthe␈αname␈αwith␈αits␈αdefinition.␈α This␈αis␈αanalogous␈αto␈αwhat␈αthe␈αLISP␈α␈↓αapply␈↓␈αfunction␈αwill␈αdo.
␈↓ ↓H␈↓Since␈α∞this␈α∞interpretation␈α∞of␈α∂␈↓αlabel␈↓␈α∞is␈α∞inadequate␈α∞in␈α∞general␈α∂contexts,␈α∞we␈α∞should␈α∞look␈α∞further␈α∂for␈α∞a
␈↓ ↓H␈↓general reading of ␈↓αlabel␈↓. Our hint comes from our interpretation of "<=" as an equality. Recall:
␈↓ ↓H␈↓α␈↓ β→fact ← ␈↓a solution to the equation:␈↓α f = λ[[x][x=0 → 1; ␈↓
t␈↓α → *[x;f[x-1]]]].
␈↓ ↓H␈↓What␈α
we␈α
need␈α
is␈α
a␈α
representation␈α
of␈α
an␈α
"equation-solver"␈α
which␈α
will␈α
take␈α
such␈α
an␈α
equation␈αand␈α
will
␈↓ ↓H␈↓return␈αa␈αfunction␈αwhich␈αsatisfies␈αthat␈αequation.␈αIn␈αparticular␈αwe␈αwould␈αlike␈αthe␈α␈↓↓best␈↓␈αsolution␈αin␈αthe
␈↓ ↓H␈↓sense␈α∩that␈α∩it␈α∩imposes␈α∩the␈α∩minimal␈α∩structure␈α∩on␈α∩the␈α∩function␈↓π 144␈↓.␈α∩ This␈α∩request␈α∩for␈α⊃minimality
␈↓ ↓H␈↓translates␈α
to␈α
finding␈α
the␈αfunction␈α
which␈α
satisfies␈α
the␈α
equation,␈αbut␈α
is␈α
least-defined␈α
on␈αother␈α
elements
␈↓ ↓H␈↓of␈α
the␈α∞domain.␈α
This␈α∞discussion␈α
of␈α∞"least"␈α
brings␈α∞in␈α
the␈α∞recent␈α
work␈α∞of␈α
D.␈α∞Scott␈α
and␈α∞the␈α
intuition
␈↓ ↓H␈↓behind␈α∞this␈α∂study␈α∞again␈α∂illuminates␈α∞the␈α∞distinction␈α∂between␈α∞mathematical␈α∂meaning␈α∞(denotational)
␈↓ ↓H␈↓and manipulative meaning (operational).
␈↓ ↓H␈↓Consider the following LISP definition:
␈↓ ↓H␈↓α␈↓ ∧%f <= λ[[n][n=0 → 0; ␈↓
t␈↓α → +[f[n-1];*[2;sub1[n]]]]]
␈↓ ↓H␈↓When␈αwe␈α
are␈αasked␈αwhat␈α
this␈αfunction␈αis␈α
doing,␈αmost␈αof␈α
us␈αwould␈αproceed␈α
operationally;␈αthat␈αis,␈α
we
␈↓ ↓H␈↓would␈αbegin␈α
computing␈α␈↓αf[n]␈↓␈αfor␈α
different␈αvalues␈α
of␈α␈↓αn␈↓␈α--what is ␈↓αf[0]?␈↓,␈α
what␈αis␈α
␈↓αf[1]␈↓, ... .␈αIt␈αis␈α
profitable
␈↓ ↓H␈↓to␈α∞look␈α∞at␈α∞this␈α∂process␈α∞differently:␈α∞what␈α∞we␈α∂are␈α∞doing␈α∞is␈α∞looking␈α∂at␈α∞a␈α∞␈↓↓sequence␈↓␈α∞of␈α∂functions,␈α∞call
␈↓ ↓H␈↓them ␈↓f␈↓βi␈↓'s .
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 144␈↓ Like a free group satisfies the group axioms, but imposes no other requirements.
␈↓ ↓H␈↓␈↓↓220 Imperative Constructs in LISP␈↓ (4.11␈↓
␈↓ ↓H␈↓␈↓ αXf␈↓β0␈↓ =␈↓ β8␈↓{<0,␈↓λB␈↓>,<1,␈↓λB␈↓>, ... }␈↓ εx␈↓when we begin, we know nothing.
␈↓ ↓H␈↓␈↓ αX␈↓f␈↓β1␈↓ =␈↓ β8␈↓{<0,0>,<1,␈↓λB␈↓>, ... }␈↓ εx␈↓now we know one pair.
␈↓ ↓H␈↓␈↓ αX␈↓f␈↓β2␈↓ =␈↓ β8␈↓{<0,0>,<1,1>, ... }␈↓ εx␈↓now two
␈↓ ↓H␈↓␈↓ αX␈↓f␈↓β3␈↓ =␈↓ β8␈↓{<0,0>,<1,1>,<2,4>, ... }␈↓ εx␈↓now three
␈↓ ↓H␈↓␈↓ αX ...␈↓ β8 ... ...␈↓ εx␈↓Eureka!!
␈↓ ↓H␈↓When␈α∞or␈α∞if,␈α∂we␈α∞realize␈α∞that␈α∂the␈α∞LISP␈α∞function␈α∞denotes␈α∂the␈α∞"squaring␈α∞function"␈α∂for␈α∞non-negative
␈↓ ↓H␈↓integers,␈α∩then␈α∩we␈α∩have␈α⊃moved␈α∩from␈α∩pragmatics␈α∩to␈α⊃semantics.␈α∩ The␈α∩process␈α∩of␈α∩discovering␈α⊃the
␈↓ ↓H␈↓denotation␈αmay␈αbe␈αlikened␈αto␈αa␈αlimiting␈αprocess␈αwhich␈αconverges␈αto␈αa␈αfunction␈αsatisfying␈αthe␈αLISP
␈↓ ↓H␈↓definition.
␈↓ ↓H␈↓That is:
␈↓ ↓H␈↓␈↓ ¬_␈↓λλ␈↓((n) n␈↓π2␈↓)␈↓ = limit of the ␈↓ f␈↓βi␈↓'s;
␈↓ ↓H␈↓where ␈↓f␈↓βi␈↓ may also be characterised as:
␈↓ ↓H␈↓␈↓ αx n␈↓π2␈↓ if ␈↓0␈↓≤␈↓n␈↓≤␈↓i
␈↓ ↓H␈↓f␈↓βi␈↓(n)␈↓ =
␈↓ ↓H␈↓␈↓ αx ␈↓λB␈↓ if ␈↓i␈↓<␈↓n␈↓ or ␈↓n␈↓␈↓<␈↓0␈↓
␈↓ ↓H␈↓We␈α∀may␈α∀think␈α∪of␈α∀our␈α∀"equation-solver"␈α∀as␈α∪proceeding␈α∀in␈α∀such␈α∪a␈α∀manner.␈α∀ As␈α∀with␈α∪simpler
␈↓ ↓H␈↓equations,␈αthere␈αmay␈αbe␈αseveral␈αsolutions.␈αFor␈αexample,␈αwe␈αhave␈αseen␈αthat␈αa␈αfunction,␈α␈↓αg␈↓,␈αdefined␈αto
␈↓ ↓H␈↓be␈α␈↓αn!␈↓␈αfor␈α␈↓αn␈↓ ≥␈↓α0␈↓␈αand␈α␈↓α0␈↓␈αfor␈α␈↓αn␈↓ <␈↓α0␈↓␈αalso␈αsatisfies␈αthe␈αLISP␈αdefinition␈αof␈α␈↓αfact␈↓.␈α The␈αexpected␈αsolution␈αfor
␈↓ ↓H␈↓␈↓αfact␈↓␈α∂is␈α∂undefined␈α⊂for␈α∂␈↓αn␈↓ <␈↓α0␈↓,␈α∂and␈α∂is␈α⊂therefore␈α∂"less␈α∂defined"␈α∂than␈α⊂␈↓αg␈↓.␈α∂We␈α∂would␈α∂like␈α⊂our␈α∂equation
␈↓ ↓H␈↓solver to produce a minimal solution, if possible.
␈↓ ↓H␈↓That is, ␈↓Y␈↓ applied to a term ␈↓εt␈↓ gives a function ␈↓f␈↓ satisfying ␈↓f = ␈↓εt␈↓(f)␈↓.
␈↓ ↓H␈↓␈↓ ¬g␈↓Y(␈↓εt␈↓) = ␈↓εt␈↓(Y(␈↓εt␈↓))␈↓
␈↓ ↓H␈↓Also␈α␈↓f␈↓␈αis␈αminimal␈αis␈αthe␈αsense␈αthat␈αany␈αother␈αfunction␈αwhich␈αsatisfies␈αthe␈αequation␈αis␈αmore␈αdefined
␈↓ ↓H␈↓than ␈↓f␈↓. Compare this with page 218. The result there says for any ␈↓εt␈↓
␈↓ ↓H␈↓␈↓ β|␈↓Y(␈↓εt␈↓) = h(h)␈↓ where ␈↓h(g) = ␈↓εt␈↓( ␈↓λλ␈↓((x) g(g(x))))␈↓.
␈↓ ↓H␈↓Such␈αan␈α
equation␈αsolver␈α␈↓↓does␈↓␈α
exist;␈αit␈αis␈α
called␈αthe␈α␈↓↓fixed-point␈α
operator␈↓.␈αIt␈αis␈α
designated␈αhere␈αby␈α
␈↓Y␈↓.
␈↓ ↓H␈↓To comprehend ␈↓Y␈↓ we generalize from the previous example.
␈↓ ↓H␈↓␈↓↓4.11␈↓ π[Rapprochement: In Retrospect 221␈↓
␈↓ ↓H␈↓In terms of our example we want a solution to ␈↓f = ␈↓λt␈↓(f)␈↓, where:
␈↓ ↓H␈↓␈↓ ∧3␈↓λt␈↓(g) = ␈↓λλ␈↓((n) if(n=0, 0, g(n-1)+2*n-1))␈↓,
␈↓ ↓H␈↓Our previous discussion leads us to believe that ␈↓λλ␈↓((n) n␈↓π2␈↓) ␈↓for ␈↓n ␈↓≥␈↓0␈↓ is the desired solution.
␈↓ ↓H␈↓How␈αdoes␈αthis␈αdiscussion␈αrelate␈αto␈αthe␈αsequence␈αof␈αfunctions␈α␈↓f␈↓βi␈↓?␈α Let's␈αlook␈αat␈αthe␈αbehavior␈αof␈α␈↓λt␈↓␈αfor
␈↓ ↓H␈↓various arguments. The simplest function is the totally undefined function, ␈↓λB␈↓ ␈↓π 145␈↓.
␈↓ ↓H␈↓␈↓ ∧,␈↓λt␈↓(␈↓λB␈↓) = ␈↓λλ␈↓((n) if(n=0, 0, ␈↓λB␈↓(n-1)+2*n-1))␈↓,
␈↓ ↓H␈↓but this says ␈↓λt␈↓(␈↓λB␈↓)␈↓ is just ␈↓f␈↓β1␈↓. Similarly,
␈↓ ↓H␈↓␈↓ ∧⊗␈↓λt␈↓(␈↓λt␈↓(␈↓λB␈↓)) = ␈↓λλ␈↓((n) if(n=0, 0, f␈↓β1␈↓(n-1)+2*n-1))␈↓,
␈↓ ↓H␈↓is just ␈↓f␈↓β2␈↓. Writing ␈↓λt␈↓πi␈↓ for the composition of ␈↓λt␈↓...␈↓λt␈↓, i times, ␈↓π 146␈↓ we can say
␈↓ ↓H␈↓␈↓ ¬s␈↓f␈↓βi␈↓ = ␈↓λt␈↓πi␈↓(␈↓λB␈↓)␈↓ or,
␈↓ ↓H␈↓␈↓ ¬1␈↓λλ␈↓((n)n␈↓π2␈↓)␈↓ = lim␈↓βi → ∞␈↓λt␈↓πi␈↓(␈↓λB␈↓)␈↓.
␈↓ ↓H␈↓It can be shown that the least fixed-point of an equation ␈↓f = ␈↓λt␈↓(f)␈↓ satisfies the relation:
␈↓ ↓H␈↓␈↓ ¬I␈↓Y(␈↓λt␈↓) = lim␈↓βi→∞␈↓λt␈↓πn␈↓(␈↓λB␈↓).␈↓
␈↓ ↓H␈↓So the denotation for ␈↓αlabel␈↓ might be better described by:
␈↓ ↓H␈↓␈↓ ∧∪␈↓λD␈↓βa␈↓∞(␈↓αlabel[␈↓ f␈↓;␈↓ g␈↓]␈↓∞)␈↓(l)␈↓ = ␈↓Y(␈↓λλ␈↓(h)␈↓λD␈↓βa␈↓∞(␈↓ g␈↓∞)␈↓(l␈↓ : ␈↓<f,h>))␈↓.
␈↓ ↓H␈↓rather than:
␈↓ ↓H␈↓␈↓ ∧≤␈↓λD␈↓βa␈↓∞(␈↓αlabel[␈↓ f␈↓;␈↓ g␈↓]␈↓∞)␈↓(l)␈↓ = ␈↓λD␈↓βa␈↓∞(␈↓ g␈↓∞)␈↓(l : <f,␈↓λD␈↓βa␈↓∞(␈↓ g␈↓∞)␈↓>)␈↓.
␈↓ ↓H␈↓The␈α∪characterizations␈α∪are␈α∀not␈α∪equivalent.␈α∪The␈α∪behavior␈α∀of␈α∪␈↓λD␈↓βa␈↓∞(␈↓αlabel[car;car]␈↓∞)␈↓␈α∪will␈α∀exhibit␈α∪a
␈↓ ↓H␈↓discrepancy.␈α∂ The␈α∂fix-point␈α∂characterization␈α∂reduces␈α∂␈↓αlabel[car;car]␈↓␈α∂to␈α∂the␈α∂minimal␈α∂solution␈α∂of␈α∂the
␈↓ ↓H␈↓equation␈α
␈↓car =car␈↓;␈α
that␈α
solution␈α∞is␈α
␈↓λB␈↓.␈α
The␈α
LISP␈α∞interpretation␈α
of␈α
␈↓αlabel[car;car]␈↓␈α
gives␈α∞␈↓car␈↓.␈α
The
␈↓ ↓H␈↓general␈α∞question␈α∞of␈α∞the␈α
correctness␈α∞of␈α∞the␈α∞denotational␈α∞semantics␈α
which␈α∞we␈α∞are␈α∞developing␈α∞is␈α
the
␈↓ ↓H␈↓subject of [Gor 73].
␈↓ ↓H␈↓In␈α
summary,␈α
LISP␈α
has␈α
two␈α
ways␈α
of␈α
assigning␈α
values␈α
to␈α
functions:␈α
␈↓αlabel␈↓␈α
and␈α
<=.␈α
The␈α
use␈α
of␈α
␈↓αlabel␈↓
␈↓ ↓H␈↓manufactures␈α∀a␈α∃new␈α∀"knotted"␈α∀environment␈α∃but␈α∀does␈α∀not␈α∃always␈α∀find␈α∀the␈α∃mimimal␈α∀solution
␈↓ ↓H␈↓[Gor 73].␈α
The␈αevaluation␈α
of␈α␈↓αf <= ␈↓λf␈↓␈α
is␈αinterpreted␈α
as␈α␈↓αf ← ␈↓λf␈↓,␈α
where␈αthe␈α
assignment␈αis␈α
made␈α
in␈αthe
␈↓ ↓H␈↓global␈α∪environment.␈α∪ LISP's␈α∪solutions␈α∪are␈α∪sufficient␈α∪for␈α∪most␈α∪definitions,␈α∪but␈α∪a␈α∪more␈α∪general
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 145␈↓ This ␈↓λB␈↓ is the totally undefined function in ␈↓[␈↓ Fn␈↓ → ␈↓ Fn␈↓]␈↓.
␈↓ ↓H␈↓␈↓π 146␈↓ Define ␈↓λt␈↓π0␈↓ to be ␈↓λB␈↓ in ␈↓[␈↓ Fn␈↓→␈↓ Fn␈↓]␈↓.
␈↓ ↓H␈↓␈↓↓222 Imperative Constructs in LISP␈↓ (4.11␈↓
␈↓ ↓H␈↓treatment␈α∃of␈α∃the␈α∃ideas␈α∃involved␈α∃in␈α∃function␈α∃definitions␈α∃is␈α∃needed␈α∃from␈α∃both␈α∃practical␈α∀and
␈↓ ↓H␈↓theoretical considerations.
␈↓ ↓H␈↓A␈α∪mathematical␈α∪treatment␈α∀of␈α∪the␈α∪imperative␈α∪features␈α∀of␈α∪programming␈α∪languages␈α∀requires␈α∪an
␈↓ ↓H␈↓extension␈α⊗of␈α∃our␈α⊗model.␈α∃An␈α⊗essential␈α∃ingredient␈α⊗of␈α∃imperatives␈α⊗is␈α∃their␈α⊗ability␈α⊗to␈α∃produce
␈↓ ↓H␈↓side-effects.␈αThis␈αis␈αusually␈αmodelled␈αby␈αincluding␈αsome␈αnotion␈αof␈α"the␈αstate␈αof␈αthe␈αmachine".␈αThen
␈↓ ↓H␈↓our ␈↓εD␈↓ function is specified in terms of an expression, an environment, and a state.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I␈α∞The␈α
␈↓αfoo-fact-baz␈↓␈α∞example␈α∞of␈α
page 217␈α∞is␈α∞not␈α
described␈α∞directly␈α
in␈α∞LISP.␈α∞Can␈α
you␈α∞write␈α∞a␈α
LISP
␈↓ ↓H␈↓program without ␈↓αprog␈↓s which will also exemplify this difficulty?
␈↓ ↓H␈↓␈↓ ¬-␈↓↓4.12 The LISP Machine␈↓
␈↓ ↓H␈↓The␈α∞LISP␈α∞definitions␈α∞and␈α∞expressions␈α∞which␈α∞we␈α∞have␈α∞been␈α∞writing␈α∞are␈α∞expressed␈α∞in␈α∞a␈α
language
␈↓ ↓H␈↓called␈α∂the␈α∂␈↓↓meta-language␈↓,␈α∞and␈α∂the␈α∂LISP␈α∞expressions␈α∂are␈α∂called␈α∞M-expressions␈α∂or␈α∂M-exprs.␈α∞ The
␈↓ ↓H␈↓most␈αprimitive␈α
data␈αstructures␈α
of␈αLISP␈α
are␈αcalled␈αS-expressions.␈α
We␈αhave␈α
seen␈αthat␈α
it␈αis␈αpossible␈α
to
␈↓ ↓H␈↓represent␈α∂M-expressions␈α⊂as␈α∂S-expressions,␈α⊂and␈α∂indeed,␈α⊂that␈α∂significant␈α⊂results␈α∂are␈α⊂obtained␈α∂from
␈↓ ↓H␈↓such␈α⊂a␈α∂mapping.␈α⊂ The␈α∂␈↓↓programming␈α⊂language␈↓,␈α∂LISP,␈α⊂uses␈α∂the␈α⊂S-expr␈α∂translation␈α⊂of␈α⊂the␈α∂LISP
␈↓ ↓H␈↓algorithms.␈α∪ As␈α∀we␈α∪move␈α∀from␈α∪the␈α∀more␈α∪formal␈α∀aspects␈α∪of␈α∀LISP␈α∪to␈α∀the␈α∪practical␈α∀details␈α∪of
␈↓ ↓H␈↓implementations␈α⊗and␈α⊗applications,␈α⊗we␈α⊗should␈α⊗examine␈α∃some␈α⊗of␈α⊗the␈α⊗features␈α⊗of␈α⊗LISP␈α⊗as␈α∃a
␈↓ ↓H␈↓programming language.
␈↓ ↓H␈↓The␈αarguments␈αto␈αLISP␈α
programs␈αare␈αS-exprs␈αand␈αsince␈α
we␈αare␈αwriting␈αLISP␈αprograms␈α
in␈αS-expr
␈↓ ↓H␈↓form,␈αthen␈αdata␈αand␈αprogram␈αare␈αindistinguishable.␈α Programs␈αmust␈αhave␈αa␈αvery␈α
special␈αstructure,
␈↓ ↓H␈↓but␈α
program␈α
and␈α
data␈α
are␈α
both␈α
S-exprs␈αjust␈α
as␈α
in␈α
most␈α
hardware␈α
machines␈α
the␈α
contents␈αof␈α
locations
␈↓ ↓H␈↓which␈α∂contain␈α∂data␈α∂are␈α∂not␈α∂distinguishable␈α∞from␈α∂locations␈α∂which␈α∂contain␈α∂instructions␈↓π 147␈↓.␈α∂ On␈α∞a
␈↓ ↓H␈↓typical␈α
contemporary␈αmachine␈α
it␈αis␈α
the␈αway␈α
in␈αwhich␈α
a␈αlocation␈α
is␈αaccessed␈α
which␈α
determines␈αhow
␈↓ ↓H␈↓the␈α
contents␈α
of␈α
that␈α
location␈α
are␈α
interpreted.␈α
If␈α
a␈α
processor␈α
accesses␈α
the␈α
location␈α
via␈α
the␈α
program
␈↓ ↓H␈↓counter,␈αthe␈αcontents␈αare␈αexecuted␈αas␈αan␈αinstruction.␈α That␈αsame␈αlocation␈αcan␈αusually␈αbe␈αaccessed␈αas
␈↓ ↓H␈↓part␈α∂of␈α∞a␈α∂data␈α∞manipulating␈α∂instruction.␈α∞ In␈α∂that␈α∂case,␈α∞the␈α∂contents␈α∞are␈α∂simply␈α∞taken␈α∂to␈α∂be␈α∞data.
␈↓ ↓H␈↓LISP␈α∀is␈α∀one␈α∀of␈α∀the␈α∀few␈α∀high-level␈α∀languages␈α∀which␈α∀also␈α∀has␈α∀this␈α∀property␈↓π 148␈↓␈α∀It␈α∀gives␈α∪the
␈↓ ↓H␈↓programmer exceptional power.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 147␈↓␈α⊃A␈α⊃few␈α⊃machines␈α⊃␈↓↓have␈↓␈α⊂been␈α⊃built␈α⊃to␈α⊃enforce␈α⊃a␈α⊂dichotomy␈α⊃between␈α⊃data␈α⊃and␈α⊃program;␈α⊂the
␈↓ ↓H␈↓HP3000 and several of the Burroughs machines ([Org 73], [Dor 76]) follow this approach.
␈↓ ↓H␈↓␈↓π 148␈↓␈αThe␈αIPL␈αseries␈α
of␈αlanguages␈α([New 61])␈αhad␈αthis␈α
property,␈αhowever␈αthose␈αlanguages␈αwere␈α
more
␈↓ ↓H␈↓reminiscent of assembly language.
␈↓ ↓H␈↓␈↓↓4.12␈↓ λzThe LISP Machine 223␈↓
␈↓ ↓H␈↓The␈α⊂processor␈α⊃of␈α⊂a␈α⊂"LISP␈α⊃machine"␈α⊂is␈α⊂␈↓αeval␈↓␈↓π 149␈↓.␈α⊃ If␈α⊂␈↓αeval␈↓␈α⊂references␈α⊃an␈α⊂S-expr␈α⊂via␈α⊃its␈α⊂"program
␈↓ ↓H␈↓counter",␈α∞then␈α∞that␈α
S-expr␈α∞is␈α∞decoded␈α
via␈α∞the␈α∞internals␈α∞of␈α
␈↓αeval␈↓.␈α∞ If␈α∞an␈α
S-expr␈α∞is␈α∞referenced␈α∞as␈α
an
␈↓ ↓H␈↓argument,␈αthen␈αit␈αis␈αtaken␈αas␈αdata␈↓π 150␈↓.␈α The␈αidentity␈αof␈αprogram␈αand␈αdata␈αis␈αnot␈αfixed␈αeven␈αwithin
␈↓ ↓H␈↓the␈α⊂execution;␈α⊂a␈α⊂LISP␈α⊂program␈α⊂can␈α⊂create␈α⊂a␈α⊂data␈α⊂structure␈α⊂which␈α⊂can␈α⊂then␈α⊂be␈α⊂executed␈α⊂either
␈↓ ↓H␈↓explicitly,␈αby␈αappearing␈αas␈αan␈αargument␈αto␈α␈↓αeval␈↓,␈αor␈αimplicitly,␈αby␈αappearing␈αin␈αthe␈αfunction-position
␈↓ ↓H␈↓of an application.
␈↓ ↓H␈↓The␈αsimplest␈αway␈αto␈αcommunicate␈αwith␈αsuch␈αa␈αmachine␈αis␈αto␈αread␈αan␈αS-expr␈αtranslation␈αof␈αa␈αLISP
␈↓ ↓H␈↓expression␈α
into␈α
memory,␈α
evaluate␈α
the␈α
expression,␈α
and␈α
print␈α
the␈α
result.␈α
Several␈α
implementations␈αof
␈↓ ↓H␈↓LISP use a variant of this "␈↓αread-eval-print␈↓" loop:
␈↓ ↓H␈↓α␈↓ ¬_prog[[]
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ¬Xa␈↓ ¬xprint[eval[read[];( )]];
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ¬X␈↓ ¬xgo[a]].
␈↓ ↓H␈↓Note the similarity to ␈↓αloop␈↓ on page 195␈↓π 151␈↓.
␈↓ ↓H␈↓List-notation␈α⊂is␈α⊂a␈α∂recognizable␈α⊂input␈α⊂and␈α⊂the␈α∂output␈α⊂from␈α⊂LISP␈α∂programs␈α⊂will␈α⊂be␈α⊂converted␈α∂to
␈↓ ↓H␈↓list-notation␈α
wherever␈α
possible.␈α
But␈αthat's␈α
where␈α
things␈α
stand.␈αLISP␈α
will␈α
allow␈α
you␈α
to␈αmanipulate
␈↓ ↓H␈↓the␈α␈↓↓representation␈↓␈αof␈αthe␈αlists.␈α The␈αLISP␈αS-expr␈αoperations␈αlike␈α␈↓αcar,␈αcdr␈↓,␈αand␈α␈↓αcons␈↓␈αoperate␈αwithout
␈↓ ↓H␈↓complaint␈α⊃on␈α⊃lists,␈α⊃even␈α⊂though␈α⊃we␈α⊃have␈α⊃repeatedly␈α⊂said␈α⊃that␈α⊃these␈α⊃functions␈α⊃are␈α⊂S-expression
␈↓ ↓H␈↓functions.␈α LISP's␈αattitude␈αtoward␈α␈↓αcar␈↓␈αand␈α␈↓αcdr␈↓␈αis␈αsimilar␈αto␈αits␈αtreatment␈αof␈α␈↓αgo␈↓s␈αand␈αlabels:␈αthese␈α
are
␈↓ ↓H␈↓useful␈α⊃primitives␈α⊃out␈α⊃of␈α⊃which␈α⊃to␈α⊃build␈α⊃"real"␈α⊃tools;␈α⊃either␈α⊃real␈α⊃data␈α⊃structures␈α⊃or␈α⊃real␈α⊂control
␈↓ ↓H␈↓structures.
␈↓ ↓H␈↓However␈αthe␈αeffect␈αof␈αthis␈αbehavior␈αis␈αto␈αpresent␈αthe␈αLISP␈αuser␈αwith␈αan␈αincredible␈αpotentiality␈αfor
␈↓ ↓H␈↓generating␈α∞programming␈α∞errors.␈α∞ It␈α
also␈α∞removes␈α∞from␈α∞the␈α∞user␈α
a␈α∞powerful␈α∞debugging␈α∞tool.␈α∞If␈α
we
␈↓ ↓H␈↓write␈α∂programs␈α∂such␈α∂that␈α∂the␈α∞type␈α∂of␈α∂each␈α∂data␈α∂object␈α∂must␈α∞be␈α∂given␈↓π 152␈↓,␈α∂and␈α∂if␈α∂we␈α∂write␈α∞each
␈↓ ↓H␈↓function␈α∂such␈α∂that␈α∂the␈α∂process␈α∂of␈α∂binding␈α⊂arguments␈α∂to␈α∂values␈α∂must␈α∂check␈α∂that␈α∂the␈α∂type␈α⊂of␈α∂the
␈↓ ↓H␈↓actual␈αparameter␈αagrees␈αwith␈αthe␈α
type␈αof␈αthe␈αparameter␈αof␈α
the␈αfunction,␈αthen␈αa␈αvery␈α
large␈αnumber
␈↓ ↓H␈↓of␈α∩programming␈α∪errors␈α∩can␈α∩be␈α∪located␈α∩almost␈α∪as␈α∩soon␈α∩as␈α∪they␈α∩occur.␈α∩ You␈α∪can␈α∩think␈α∪of␈α∩the
␈↓ ↓H␈↓parameter-passing␈α∂mechanism␈α∂as␈α∂sort␈α∂of␈α∂a␈α∂"fire-wall",␈α∂which␈α∂will␈α∂attempt␈α∂to␈α∂contain␈α⊂the␈α∂deviant
␈↓ ↓H␈↓behavior within the particular function.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 149␈↓␈α∞Several␈α∞"LISP␈α
machines"␈α∞have␈α∞been␈α
proposed␈α∞or␈α∞actually␈α
built␈α∞including:␈α∞[Got 74],␈α
[Gre 74],
␈↓ ↓H␈↓[Deu 73], and [Bar 71]
␈↓ ↓H␈↓␈↓π 150␈↓ This goes for ␈↓αfunarg␈↓s as well: until they're applied, they're data.
␈↓ ↓H␈↓␈↓π 151␈↓␈α
The␈α
details␈α
of␈α
␈↓αread␈↓␈α
and␈α
␈↓αprint␈↓,␈α
two␈α
of␈α
the␈α
input␈α
and␈α
output␈α
operations␈α
in␈α
LISP,␈α
are␈αdiscussed␈α
in
␈↓ ↓H␈↓the next chapter.
␈↓ ↓H␈↓␈↓π 152␈↓␈α∀For␈α∀example,␈α∀in␈α∀Section 2.3␈α∀the␈α∀types␈α∀of␈α∀the␈α∀arguments␈α∀to␈α∀␈↓αdiff␈↓␈α∀should␈α∀be␈α∀<poly>␈α∀and
␈↓ ↓H␈↓<variable>, ␈↓↓not␈↓ list and atom.
␈↓ ↓H␈↓␈↓↓224 Imperative Constructs in LISP␈↓ &4.12␈↓
␈↓ ↓H␈↓Any␈αfunction␈α
which␈αgets␈αcalled␈α
has␈αa␈αright␈α
to␈αexpect␈αthat␈α
it␈αwill␈αbe␈α
called␈αwith␈α
reasonable␈αvalues.
␈↓ ↓H␈↓Part␈αof␈αbeing␈αreasonable␈αis␈αhaving␈αthe␈αcorrect␈αnumber␈αof␈αarguments␈αgiven␈αto␈αit;␈α␈↓αcons[A; B; C]␈↓␈αis␈αas
␈↓ ↓H␈↓bad␈α∞as␈α
␈↓αcons[A]␈↓.␈α∞Part␈α
of␈α∞being␈α
reasonable␈α∞is␈α∞having␈α
the␈α∞right␈α
kind␈α∞of␈α
arguments;␈α∞we␈α∞don't␈α
expect
␈↓ ↓H␈↓results␈αfrom␈α
␈↓αsub1[A]␈↓.␈α We␈α
should␈αnot␈α
expect␈αthat␈α
the␈αfunctions␈α
are␈αsufficiently␈α
omniscient␈αto␈α
convert
␈↓ ↓H␈↓an␈αargument␈αof␈αthe␈αwrong␈αkind␈αinto␈αa␈αproper␈αone.␈α If␈αa␈αfunction␈αis␈αwritten␈αto␈αexpect␈αan␈αargument
␈↓ ↓H␈↓of␈αtype␈α␈↓αpolynomial␈↓␈αthen␈αit␈αshould␈αcomplain␈αif␈αit␈αreceives␈αan␈αargument␈αof␈αtype␈α␈↓αlist␈↓␈αeven␈αthough␈αthe
␈↓ ↓H␈↓current representation for polynomials might be special instances of lists.
␈↓ ↓H␈↓Many␈α∞programming␈α∂languages␈α∞␈↓↓do␈↓␈α∂offer␈α∞such␈α∂omniscience.␈α∞Fortran␈α∂calls␈α∞this␈α∂service␈α∞"conversion";
␈↓ ↓H␈↓Algol68␈α
calls␈α∞it␈α
␈↓↓"coercion"␈↓.␈α
However␈α∞if␈α
each␈α
function␈α∞accepts␈α
whatever␈α
argument␈α∞it␈α
is␈α∞given␈α
and
␈↓ ↓H␈↓attempts␈α
to␈α
use␈α
it␈αin␈α
its␈α
computation,␈α
then␈αthe␈α
first␈α
indication␈α
of␈αtrouble␈α
will␈α
occur␈α
when␈αa␈α
primitive
␈↓ ↓H␈↓function␈αis␈αcalled␈αand␈αcauses␈αsome␈αerror␈αdeep␈αwithin␈αthe␈αimplementation.␈α Typically␈αthis␈αindication
␈↓ ↓H␈↓of␈α
error␈αis␈α
way␈αpast␈α
the␈αactual␈α
source␈αof␈α
the␈α
difficulty.␈αThe␈α
alternative␈αis␈α
to␈αexplicitly␈α
code␈αtests␈α
into
␈↓ ↓H␈↓the␈α∞entry␈α
code␈α∞of␈α
each␈α∞function␈α
definition;␈α∞but␈α
that's␈α∞an␈α
expensive␈α∞use␈α
of␈α∞the␈α∞programmer's␈α
time
␈↓ ↓H␈↓and␈α⊂the␈α⊂computation␈α⊂time.␈α⊂ What␈α⊂typically␈α⊂happens␈α⊂is␈α⊂that␈α⊂the␈α⊂tests␈α⊂are␈α⊂left␈α⊂out␈α⊂and␈α⊂intensive
␈↓ ↓H␈↓debugging soon follows.
␈↓ ↓H␈↓As␈αwith␈αmost␈αareas␈αof␈αprogramming,␈αcoercion␈α
is␈αnot␈αa␈αblack-or-white␈αissue.␈α A␈αstrong␈αtype␈α
structure
␈↓ ↓H␈↓can␈α∀hinder␈α∪as␈α∀well␈α∀as␈α∪help.␈α∀Requiring␈α∪explicit␈α∀declarations␈α∀and␈α∪directions␈α∀for␈α∀conversion␈α∪is
␈↓ ↓H␈↓frequently␈αannoying.␈αIndeed␈αseveral␈αimportant␈αprograms␈αare␈αtype-free.␈αIn␈αparticular,␈αthe␈αdebugging
␈↓ ↓H␈↓programs␈αmust␈αbe␈αable␈αto␈αfreely␈αaccess␈αall␈αparts␈αof␈αthe␈αrepresentation␈αof␈αprogram␈αand␈αdata␈αwithout
␈↓ ↓H␈↓regard for type.
␈↓ ↓H␈↓LISP's␈α
position␈αis␈α
that␈α
it␈αis␈α
the␈αuser's␈α
responsibility␈α
to␈αhandle␈α
all␈αtype␈α
restrictions␈α
by␈αprogrammed
␈↓ ↓H␈↓tests.␈α∂ LISP␈α∂has␈α∂no␈α∂capability␈α∂to␈α∂define␈α∂and␈α∂maintain␈α∂abstract␈α∂data␈α∂structures.␈α⊂ However␈α∂people
␈↓ ↓H␈↓have␈α∞begun␈α∞investigations␈α
of␈α∞"typed␈α∞LISP"␈α
[Car 76],␈α∞and␈α∞some␈α
implementations␈α∞of␈α∞LISP␈α
[Int 75]
␈↓ ↓H␈↓give some aids in constructing and maintaining typed data structures.
␈↓ ↓H␈↓Symbolic␈αexpressions␈αare␈α
the␈αonly␈αreal␈α
data␈αstructure;␈αwe␈α
almost␈αhave␈αsequences␈α
as␈αa␈αdata␈α
structure,
␈↓ ↓H␈↓and␈α⊃the␈α∩necessary␈α⊃ingredients␈α⊃are␈α∩there␈α⊃to␈α⊃build␈α∩abstract␈α⊃data␈α⊃structures.␈α∩But␈α⊃the␈α∩question␈α⊃of
␈↓ ↓H␈↓integrity␈α∞in␈α
using␈α∞such␈α∞defined␈α
data␈α∞structures␈α∞is␈α
left␈α∞totally␈α
in␈α∞the␈α∞hands␈α
of␈α∞the␈α∞programmer.␈α
In
␈↓ ↓H␈↓summary,␈αLISP␈αis␈αan␈αexcellent␈αtool␈αfor␈αbuilding␈αmore␈αcomplex␈αsystems;␈αas␈αa␈αtool,␈αit␈αhas␈αthe␈αability
␈↓ ↓H␈↓to␈αcause␈αinjury,␈αand␈αsince␈αit␈αis␈αa␈αtool␈αit␈αhas␈αfew␈αpreconceptions.␈αThese␈αare␈αsome␈αof␈αthe␈αreasons␈αthat
␈↓ ↓H␈↓LISP has maintained its position as the "machine language" for artificial intelligence.
␈↓ ↓H␈↓␈↓↓5.␈↓ /static structure 225␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓↓CHAPTER 5
␈↓ ↓H␈↓↓␈↓ β_IMPLEMENTATION OF THE STATIC STRUCTURE OF LISP␈↓
␈↓ ↓H␈↓␈↓ ¬`␈↓↓5.1 Introduction␈↓
␈↓ ↓H␈↓The␈αmaterial␈αin␈αthe␈α
previous␈αchapters␈αhas␈αbeen␈αrather␈α
abstract.␈α This␈αchapter␈αbegins␈α
a␈αdiscussion
␈↓ ↓H␈↓of␈α∩the␈α⊃mechanisms␈α∩which␈α∩occur␈α⊃in␈α∩implementations␈α⊃of␈α∩LISP.␈α∩However␈α⊃the␈α∩importance␈α∩of␈α⊃the
␈↓ ↓H␈↓techniques␈α⊂we␈α⊂will␈α⊂describe␈α∂extends␈α⊂far␈α⊂beyond␈α⊂the␈α∂implementation␈α⊂of␈α⊂this␈α⊂particular␈α∂language.
␈↓ ↓H␈↓Most␈α→of␈α_the␈α→ideas␈α_involved␈α→in␈α→our␈α_implementation␈α→are␈α_now␈α→considered␈α→standard␈α_system
␈↓ ↓H␈↓programming␈αtechniques␈αand␈αare␈αcommon␈αtools␈αin␈αlanguage␈αdesign.␈αLISP␈αis␈αparticularly␈α
well-suited
␈↓ ↓H␈↓to␈α_the␈α_task␈α→of␈α_explicating␈α_these␈α_ideas␈α→since␈α_many␈α_find␈α_their␈α→origins␈α_in␈α_the␈α→first␈α_LISP
␈↓ ↓H␈↓implementation.
␈↓ ↓H␈↓We␈α↔will␈α↔begin␈α↔our␈α↔discussion␈α↔of␈α⊗implementation␈α↔with␈α↔an␈α↔analysis␈α↔of␈α↔storage␈α↔regimes␈α⊗for
␈↓ ↓H␈↓S-expressions.␈α
As␈α
with␈α
the␈α
more␈α
abstract␈α
discussions␈α
of␈α
representations,␈α
the␈α
"concrete"␈α
representation
␈↓ ↓H␈↓which␈α→we␈α→pick␈α→for␈α~our␈α→data␈α→structures␈α→(S-expressions)␈α~will␈α→have␈α→direct␈α→bearing␈α~on␈α→the
␈↓ ↓H␈↓implementation␈α∞of␈α∞the␈α∞primitive␈α
constructor␈α∞(␈↓αcons␈↓),␈α∞selectors␈α∞(␈↓αcar,␈α
cdr␈↓)␈α∞and␈α∞predicates␈α∞(␈↓αatom,␈α∞eq␈↓)␈α
of
␈↓ ↓H␈↓LISP.
␈↓ ↓H␈↓Since␈αwe␈αare␈αnow␈αto␈αbecome␈αmore␈αpractical,␈αwe␈αmust␈αconsider␈αthe␈αefficiency␈αof␈αthe␈αimplementation
␈↓ ↓H␈↓and␈α
we␈α
must␈αinclude␈α
input␈α
and␈α
output␈αmechanisms␈α
so␈α
that␈α
the␈αlanguage␈α
may␈α
communicate␈αwith␈α
the
␈↓ ↓H␈↓external world.
␈↓ ↓H␈↓The␈α
present␈α
chapter␈α
will␈α
develop␈α
a␈α
picture␈α
of␈α
the␈α
␈↓↓static␈↓␈α
structure␈α
of␈α
an␈α
implementation,␈α
or␈α∞to␈α
be
␈↓ ↓H␈↓more␈α
graphic,␈αthis␈α
chapter␈α
describes␈αthe␈α
memory␈α
of␈αa␈α
LISP␈α
machine.␈α The␈α
next␈α
chapter␈αdiscusses
␈↓ ↓H␈↓the␈α∂␈↓↓dynamic␈α∂structure␈↓␈α∂of␈α∂LISP;␈α∂that␈α⊂is,␈α∂the␈α∂control␈α∂structures␈α∂necessary␈α∂to␈α⊂evaluate␈α∂expressions
␈↓ ↓H␈↓involving recursive functions and other LISP constructs.
␈↓ ↓H␈↓Throughout␈αthese␈αdiscussions␈α
we␈αwill␈αremain␈αas␈α
abstract␈αas␈αpossible␈α
without␈αlosing␈αtoo␈αmuch␈α
detail.
␈↓ ↓H␈↓We␈α∃will␈α∀describe␈α∃the␈α∀"logical"␈α∃structure␈α∃of␈α∀a␈α∃LISP␈α∀machine,␈α∃even␈α∀though␈α∃a␈α∃more␈α∀efficient
␈↓ ↓H␈↓implementation␈α
might␈αmap␈α
differing␈α
logical␈αstructures␈α
onto␈α
the␈αsame␈α
physical␈α
structures␈αby␈α
utilizing
␈↓ ↓H␈↓machine-dependent techniques.
␈↓ ↓H␈↓␈↓↓226 static structure␈↓ 45.2␈↓
␈↓ ↓H␈↓␈↓ ∧\␈↓↓5.2 Representation of S-expressions␈↓
␈↓ ↓H␈↓We previously have expressed the dotted pair ␈↓α(A . (B . C))␈↓ as:
␈↓"␈↓ ↓H␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ / /\
␈↓"␈↓ ↓H␈↓∂ / / \
␈↓"␈↓ ↓H␈↓∂ ␈↓αA␈↓∂ ␈↓αB␈↓∂ ␈↓αC␈↓∂
␈↓ ↓H␈↓or occasionally (see page 8) as:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
ααααα→~ # ~ #αβααααααααααα→~ # ~ # ~
␈↓"␈↓ ↓H␈↓
%αβα∀ααα$ %αβα∀αβα$
␈↓"␈↓ ↓H␈↓
↓ ↓ ↓
␈↓"␈↓ ↓H␈↓
␈↓αA␈↓
␈↓αB␈↓
␈↓αC␈↓
␈↓ ↓H␈↓This␈α∞second␈α∞style␈α∞of␈α
graphical␈α∞representation␈α∞has␈α∞a␈α∞direct␈α
representation␈α∞in␈α∞the␈α∞storage␈α∞layout␈α
of
␈↓ ↓H␈↓our␈αmachine.␈α Each␈α
"double-box"␈αwill␈αbe␈αrepresented␈α
by␈αa␈αmachine␈αlocation␈α
and␈αeach␈αarrow␈αwill␈α
be
␈↓ ↓H␈↓represented␈α∩as␈α∩a␈α∩␈↓↓pointer␈↓␈α⊃to␈α∩a␈α∩machine␈α∩location.␈α∩ Notice␈α⊃that␈α∩each␈α∩box␈α∩contains␈α∩two␈α⊃pointers;
␈↓ ↓H␈↓therefore␈αeach␈αcorresponding␈αmachine␈αlocation,␈α␈↓
loc␈↓,␈αwill␈αbe␈αinterpreted␈αas␈αcontaining␈αtwo␈αmachine
␈↓ ↓H␈↓addresses␈↓π 153␈↓.␈α⊃The␈α⊃left-hand␈α⊃address␈α⊃will␈α⊃represent␈α⊃the␈α⊃␈↓αcar␈↓-branch;␈α⊃the␈α⊃right-hand␈α∩address␈α⊃will
␈↓ ↓H␈↓represent the ␈↓αcdr␈↓-branch:
␈↓"␈↓ ↓H␈↓
⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
loc ~ car ~ cdr ~
␈↓"␈↓ ↓H␈↓
%ααααα∀ααααα$
␈↓ ↓H␈↓The␈α∪pointers␈α∩will␈α∪either␈α∪reference␈α∩atoms␈α∪or␈α∩point␈α∪to␈α∪two-pointer␈α∩boxes.␈α∪ Literal␈α∪atoms␈α∩-- like
␈↓ ↓H␈↓␈↓αA, B, C␈↓ --␈αwill␈αalso␈αbe␈αrepresented␈αin␈αmachine␈αlocations,␈αonly␈αhere␈αthe␈αcontents␈αof␈αeach␈αlocation␈αwill
␈↓ ↓H␈↓be␈α
an␈α
encoding␈α
of␈α
the␈α
name␈αof␈α
the␈α
atom.␈α
Obviously␈α
the␈α
contents␈αof␈α
such␈α
a␈α
location␈α
must␈α
not␈αbe
␈↓ ↓H␈↓interpreted as pointers.
␈↓"␈↓ ↓H␈↓
⊂αααααααααααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
loc ~ rep. of literal atom ~
␈↓"␈↓ ↓H␈↓
%αααααααααααααααααααααα$
␈↓ ↓H␈↓To␈α⊂help␈α⊂keep␈α⊂track␈α⊃of␈α⊂the␈α⊂different␈α⊂uses␈α⊂of␈α⊃machine␈α⊂locations␈α⊂we␈α⊂will␈α⊂partition␈α⊃our␈α⊂machine's
␈↓ ↓H␈↓memory␈α⊂into␈α∂two␈α⊂disjoint␈α∂spaces:␈α⊂␈↓↓pointer␈α∂space␈↓,␈α⊂which␈α∂will␈α⊂contain␈α∂two-pointer␈α⊂cells;␈α⊂and␈α∂␈↓↓atom
␈↓ ↓H␈↓↓space␈↓,␈α⊃which␈α⊂will␈α⊃contain␈α⊃information␈α⊂like␈α⊃atoms␈α⊂which␈α⊃should␈α⊃not␈α⊂be␈α⊃interpreted␈α⊃as␈α⊂pointers.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 153␈↓␈αAn␈αactual␈αhardware␈αmachine␈αmay␈α
not␈αbe␈αof␈αsufficient␈αword-size␈αto␈αaccomodate␈α
two␈αaddresses;
␈↓ ↓H␈↓in␈α⊂this␈α⊂case,␈α⊂several␈α⊂real␈α⊂words␈α⊂may␈α⊂be␈α⊂needed␈α⊂to␈α⊂represent␈α⊂one␈α⊂LISP␈α⊂word.␈α⊂For␈α⊃example,␈α⊂the
␈↓ ↓H␈↓PDP-11␈α≠(16 bit words)␈α≠implementations␈α≠typically␈α≠use␈α≠two␈α≠machine␈α≠words␈α≤([Har 75]),␈α≠and
␈↓ ↓H␈↓micro-processor␈α
versions␈α(8 bit words)␈α
may␈αuse␈α
four␈α
words␈α([Pag 76]).␈α
In␈αSection 7.12␈α
we␈α
discuss␈αa
␈↓ ↓H␈↓special compact representation of LISP cells.
␈↓ ↓H␈↓␈↓↓5.2␈↓ πJRepresentation of S-expressions 227␈↓
␈↓ ↓H␈↓Thus␈α⊃if␈α⊃the␈α⊃first␈α⊃box␈α⊃in␈α⊃our␈α⊃example␈α⊃were␈α⊃represented␈α⊃by␈α⊃location␈α⊃␈↓
100␈↓␈α⊃and␈α⊃the␈α⊃second␈α⊂were
␈↓ ↓H␈↓represented␈α
by␈α
location␈α
␈↓
405␈↓,␈αand␈α
the␈α
atoms␈α
␈↓αA␈↓,␈α␈↓αB␈↓,␈α
and␈α
␈↓αC␈↓␈α
were␈αrepresented␈α
by␈α
the␈α
numbers␈α
␈↓
40␈↓,␈α␈↓
41␈↓,
␈↓ ↓H␈↓and␈α⊂␈↓
42␈↓,␈α⊂and␈α⊂were␈α∂to␈α⊂be␈α⊂found␈α⊂in␈α∂locations␈α⊂␈↓
710␈↓,␈α⊂␈↓
762␈↓,␈α⊂and␈α∂␈↓
711␈↓,␈α⊂respectively,␈α⊂then␈α⊂the␈α∂following
␈↓ ↓H␈↓picture beginning at location ␈↓
100␈↓ could represent the dotted pair ␈↓α(A . (B . C))␈↓.
␈↓"␈↓ ↓H␈↓
⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
100 ~ 710 ~ 405 ~
␈↓"␈↓ ↓H␈↓
%ααααα∀ααααα$
␈↓"␈↓ ↓H␈↓
...
␈↓"␈↓ ↓H␈↓
⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
405 ~ 762 ~ 711 ~
␈↓"␈↓ ↓H␈↓
%ααααα∀ααααα$
␈↓"␈↓ ↓H␈↓
...
␈↓"␈↓ ↓H␈↓
⊂ααααααααααα⊃
␈↓"␈↓ ↓H␈↓
710 ~ 40 ~
␈↓"␈↓ ↓H␈↓
εαααααααααααλ
␈↓"␈↓ ↓H␈↓
711 ~ 42 ~
␈↓"␈↓ ↓H␈↓
%ααααααααααα$
␈↓"␈↓ ↓H␈↓
...
␈↓"␈↓ ↓H␈↓
⊂ααααααααααα⊃
␈↓"␈↓ ↓H␈↓
762 ~ 41 ~
␈↓"␈↓ ↓H␈↓
%ααααααααααα$
␈↓ ↓H␈↓The␈α
left␈α
half␈αof␈α
location␈α
␈↓
100␈↓␈αpoints␈α
to␈α
the␈αrepresentation␈α
of␈α
the␈αatom␈α
␈↓αA␈↓␈α
and␈αthe␈α
right␈α
half␈αpoints␈α
to
␈↓ ↓H␈↓the␈α⊃representation␈α∩of␈α⊃the␈α∩dotted␈α⊃pair␈α⊃␈↓α(B . C)␈↓.␈α∩ Notice␈α⊃too,␈α∩that␈α⊃given␈α⊃the␈α∩entry␈α⊃point␈α∩into␈α⊃the
␈↓ ↓H␈↓representation --location ␈↓
100␈↓ in the example-- we can discover the S-expr being represented.
␈↓ ↓H␈↓This␈αrepresentation␈αof␈αS-exprs␈αis␈αa␈αspecial␈αcase␈αof␈αa␈αscheme␈αcalled␈α␈↓↓linked␈αlist␈αstructure␈↓.␈α
The␈αterm
␈↓ ↓H␈↓"linked"␈αrefers␈αto␈αthe␈αfact␈αthat␈αto␈αfind␈αsucceeding␈αelements␈αin␈αthe␈αrepresentation␈αwe␈αmust␈αfollow␈αthe
␈↓ ↓H␈↓explicit␈α∪pointers␈α∪as␈α∪opposed␈α∪to,␈α∪say,␈α∩merely␈α∪incrementing␈α∪an␈α∪array␈α∪pointer.␈α∪ The␈α∪phrase␈α∩"list
␈↓ ↓H␈↓structure"␈α∨describes␈α∨an␈α∨arbitrary␈α∨interconnection␈α∨of␈α∨these␈α∨two-pointer␈α∨nodes,␈α∨including
␈↓ ↓H␈↓self-referential␈α
structures.␈α
We␈α
will␈α
discuss␈α
such␈αgeneral␈α
structures␈α
later;␈α
for␈α
the␈α
moment␈α
we␈αrestrict
␈↓ ↓H␈↓such constructions to LISP trees: no intersecting branches␈↓π 154␈↓.
␈↓ ↓H␈↓The␈αparticular␈αbrand␈αof␈α
linked␈αlist␈αstructure␈αwhich␈αwe␈α
have␈αdemonstrated␈αis␈αcalled␈α
␈↓↓singly␈αlinked␈↓.
␈↓ ↓H␈↓The␈αadjective␈α"singly"␈αmeans␈αthat␈αonly␈α␈↓↓one␈↓␈αpointer␈αis␈αstored␈αas␈αthe␈αrepresentation␈αof␈αthe␈α
arrow,␈α␈↓
→␈↓.
␈↓ ↓H␈↓In␈α
the␈α
case␈α
of␈α
LISP,␈α
the␈α
terminology␈α
means␈αthat␈α
the␈α
representation␈α
of␈α
each␈α
pointer␈α
only␈α
tells␈αus␈α
how
␈↓ ↓H␈↓to␈α
find␈α
succeeding␈α∞elements␈α
in␈α
the␈α
structure.␈α∞For␈α
example,␈α
if␈α
we␈α∞were␈α
looking␈α
at␈α
location␈α∞␈↓
405␈↓␈α
the
␈↓ ↓H␈↓representation␈α∞tells␈α
us␈α∞how␈α∞to␈α
find␈α∞the␈α
␈↓αcar␈↓␈α∞or␈α∞␈↓αcdr␈↓;␈α
they're␈α∞at␈α
␈↓
762␈↓␈α∞and␈α∞␈↓
711␈↓␈α
respectively.␈α∞But␈α∞if␈α
we
␈↓ ↓H␈↓wanted␈α∪to␈α∪find␈α∪the␈α∩␈↓↓predecessor␈↓␈α∪of␈α∪␈↓
405␈↓␈α∪in␈α∪this␈α∩representation␈α∪it␈α∪would␈α∪require␈α∪some␈α∩further
␈↓ ↓H␈↓calculation.␈α We␈αwould␈α
have␈αto␈αstart␈αat␈α
the␈αbeginning␈αof␈αthe␈α
S-expr␈αrepresentation␈αand␈αlook␈α
for␈αa
␈↓ ↓H␈↓location␈α⊃such␈α∩that␈α⊃its␈α∩␈↓αcar␈↓␈α⊃or␈α∩␈↓αcdr␈↓␈α⊃is␈α∩the␈α⊃desired␈α∩cell.␈α⊃ If␈α∩our␈α⊃use␈α∩of␈α⊃S-exprs␈α∩required␈α⊃frequent
␈↓ ↓H␈↓discovery␈αof␈αsuch␈α
predecessors␈αthen␈αwe␈α
might␈αconsider␈αan␈α
even␈αmore␈αcomplex␈αlinked␈α
representation
␈↓ ↓H␈↓which␈α
would␈α
also␈α
contain␈α
information␈α
about␈α
the␈α
predecessor␈α
of␈α
each␈α
node,␈α
essentially␈αrepresenting␈α
␈↓
→␈↓
␈↓ ↓H␈↓as ␈↓
↔␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 154␈↓␈α∩The␈α∩implementation␈α∩of␈α∩lists␈α∩using␈α∩linked␈α∩addresses␈α∩was␈α∩introduced␈α∩by␈α∩the␈α∩IPL␈α∩series␈α⊃of
␈↓ ↓H␈↓languages; [New 61].
␈↓ ↓H␈↓␈↓↓228 static structure␈↓ 45.2␈↓
␈↓ ↓H␈↓For example:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
α←→α→~ # ~ #←βααα←→αααααα→~ # ~ # ~
␈↓"␈↓ ↓H␈↓
%αβα∀ααα$ %αβα∀αβα$
␈↓"␈↓ ↓H␈↓
↑ ↑ ↑
␈↓"␈↓ ↓H␈↓
↓ ↓ ↓
␈↓"␈↓ ↓H␈↓
␈↓αA␈↓
␈↓αB␈↓
␈↓αC␈↓
␈↓ ↓H␈↓One␈αsuch␈αrepresentation␈αis␈αcalled␈α␈↓↓doubly-linked␈αlist␈αstructure␈↓.␈αIn␈αthis␈αrepresentation␈αof␈αLISP␈αtrees
␈↓ ↓H␈↓we could store ␈↓↓three␈↓ pieces of information with each non-terminal node:
␈↓"␈↓ ↓H␈↓
⊂ααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
~ predecessor ~
␈↓"␈↓ ↓H␈↓
loc εααααααπααααααλ
␈↓"␈↓ ↓H␈↓
~ car ~ cdr ~
␈↓"␈↓ ↓H␈↓
%αααααα∀αααααα$
␈↓ ↓H␈↓Note␈α⊂that␈α⊂LISP␈α⊃trees␈α⊂always␈α⊂␈↓↓do␈↓␈α⊃have␈α⊂unique␈α⊂predecessors.␈α⊂In␈α⊃the␈α⊂case␈α⊂of␈α⊃list-structure,␈α⊂unique
␈↓ ↓H␈↓predecessors␈αdo␈αnot␈αalways␈αexist.␈αCompromises␈αexist␈αin␈αsome␈αapplications:␈αsome␈αdata␈αstructures␈αcan
␈↓ ↓H␈↓be␈αdoubly-linked,␈αallowing␈α
fast␈αtraversal␈αbut␈α
requiring␈αmore␈αspace;␈α
while␈αother␈αdata␈α
structures␈αare
␈↓ ↓H␈↓singly␈α∩linked,␈α∩requiring␈α∩less␈α∪space,␈α∩but␈α∩requiring␈α∩more␈α∪time␈α∩to␈α∩traverse␈α∩([Gua 69]);␈α∪still␈α∩other
␈↓ ↓H␈↓structures␈α∂may␈α∂have␈α∞more␈α∂compact␈α∂representation␈α∞as␈α∂arrays␈α∂or␈α∞numbers.␈α∂ For␈α∂example,␈α∂a␈α∞typical
␈↓ ↓H␈↓representation␈α⊂of␈α⊂a␈α⊂vector,␈α⊂or␈α⊂sequence␈α⊂of␈α⊂fixed␈α⊂length,␈α⊂is␈α⊂to␈α⊂store␈α⊂the␈α⊂elements␈α⊃sequentially␈α⊂in
␈↓ ↓H␈↓memory␈↓π 155␈↓.␈α∪ Since␈α∩each␈α∪element␈α∩in␈α∪this␈α∩structure␈α∪has␈α∩at␈α∪most␈α∩one␈α∪successor␈α∩we␈α∪can␈α∪use␈α∩the
␈↓ ↓H␈↓sequential␈α
addresses␈α
as␈α
implicit␈α
pointers␈α
to␈α
retrieve␈α
successive␈α
elements.␈α
A␈α
general␈α
S-expr␈α
has␈αtwo
␈↓ ↓H␈↓successors,␈αthus␈α
the␈αimplied␈α
linear␈αaddressing␈αscheme␈α
of␈αmost␈α
machine␈αmemories␈α
is␈αinsufficient␈αas␈α
it
␈↓ ↓H␈↓stands;␈α⊂LISP␈α⊂uses␈α⊂linked␈α⊂allocation.␈α⊂ Again␈α∂there␈α⊂are␈α⊂compromises.␈α⊂ For␈α⊂example,␈α⊂the␈α∂following
␈↓ ↓H␈↓memory␈αrepresentation␈αis␈αvalid␈α
for␈αLISP␈αtrees:␈αfor␈α
any␈αlocation␈α␈↓αn␈↓,␈αfind␈α
its␈αsuccessors␈αat␈αlocations␈α
␈↓α2n␈↓
␈↓ ↓H␈↓and␈α␈↓α2n+1␈↓;␈αnote␈α
that␈αthe␈αpredecessor␈α
of␈αany␈αcell␈α
is␈αunique.␈α Each␈α
location␈αmust␈αcontain␈αan␈α
indication
␈↓ ↓H␈↓of␈α⊗whether␈α∃or␈α⊗not␈α∃it␈α⊗is␈α∃an␈α⊗atom.␈α⊗ The␈α∃remaining␈α⊗contents␈α∃of␈α⊗a␈α∃location␈α⊗is␈α⊗available␈α∃for
␈↓ ↓H␈↓data [Ber 71].
␈↓ ↓H␈↓We␈α⊂will␈α⊂frequently␈α⊂refer␈α∂to␈α⊂several␈α⊂different␈α⊂S-exprs␈α∂simultaneously;␈α⊂for␈α⊂example,␈α⊂when␈α⊂we␈α∂are
␈↓ ↓H␈↓talking␈αabout␈αthe␈αimplementation␈αof␈αthe␈αfunction␈α␈↓αcons␈↓␈αwe␈αwill␈αbe␈αmanipulating␈αthe␈αrepresentations
␈↓ ↓H␈↓of␈α∞two␈α∞S-exprs.␈α∂Similarly␈α∞we␈α∞will␈α∂want␈α∞to␈α∞refer␈α∞to␈α∂several␈α∞pieces␈α∞of␈α∂a␈α∞single␈α∞complex␈α∂S-expr;␈α∞for
␈↓ ↓H␈↓example␈αwe␈αmight␈αwish␈αto␈α"put␈αa␈αfinger"␈αat␈αa␈αspecific␈αpoint␈αin␈αa␈αstructure␈αand␈αthen,␈αdepending␈αon
␈↓ ↓H␈↓the␈α
result␈αof␈α
a␈αcomputation␈α
on␈αsome␈α
sub-part,␈α
move␈αthe␈α
"finger"␈αeither␈α
left␈αor␈α
right.␈α
To␈αfacilitate
␈↓ ↓H␈↓such␈α
discussions␈α
we␈αwill␈α
assume␈α
the␈αexistence␈α
of␈α
a␈αset␈α
of␈α
pointer␈αregisters:␈α
␈↓
Pt␈↓β1␈↓,␈α
␈↓
Pt␈↓β2␈↓, ..., ␈↓
Pt␈↓βn␈↓.␈α Thus,
␈↓ ↓H␈↓using␈αthe␈αabove␈αexample,␈αthe␈αfollowing␈αrepresents␈α␈↓
Pt␈↓β1␈↓␈αpointing␈αat␈α␈↓α(B . C)␈↓␈αand␈α␈↓
Pt␈↓β2␈↓␈αpointing␈αat␈αthe
␈↓ ↓H␈↓atom ␈↓αA␈↓:
␈↓"␈↓ ↓H␈↓
Pt␈↓β1␈↓
Pt␈↓β2␈↓
␈↓"␈↓ ↓H␈↓
⊂αααααααα⊃ ⊂αααααααα⊃
␈↓"␈↓ ↓H␈↓
~ 405 ~ ~ 710 ~
␈↓"␈↓ ↓H␈↓
%αααααααα$ %αααααααα$
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 155␈↓ We will discuss these more detailed representations in Chapter 7.
␈↓ ↓H␈↓␈↓↓5.2␈↓ πJRepresentation of S-expressions 229␈↓
␈↓ ↓H␈↓Implicit␈αin␈αour␈α
representation␈αis␈αthe␈α
assurance␈αthat␈αwe␈αcan␈α
differentiate␈αbetween␈αlocations␈α
in␈αatom
␈↓ ↓H␈↓space␈αand␈αlocations␈αin␈αpointer␈αspace.␈αFor␈αexample,␈αassume␈αeach␈αof␈αour␈αlocations␈αcan␈αhold␈αsix␈αdigits
␈↓ ↓H␈↓and␈α∂assume␈α⊂we␈α∂will␈α⊂store␈α∂a␈α∂numeric␈α⊂atom␈α∂as␈α⊂its␈α∂corresponding␈α∂number.␈α⊂Then␈α∂the␈α⊂atom␈α∂␈↓α762711␈↓
␈↓ ↓H␈↓would be stored as:
␈↓"␈↓ ↓H␈↓
⊂αααααααα⊃
␈↓"␈↓ ↓H␈↓
~ 762711 ~
␈↓"␈↓ ↓H␈↓
%αααααααα$
␈↓ ↓H␈↓Since␈α∞this␈α
is␈α∞exactly␈α
the␈α∞contents␈α
of␈α∞location␈α∞␈↓
405␈↓␈↓π 156␈↓␈α
some␈α∞confusion␈α
is␈α∞possible:␈α
is␈α∞the␈α∞contents␈α
a
␈↓ ↓H␈↓number␈αor␈αis␈α
it␈αtwo␈αpointers?␈α
A␈αtypical␈αtrick␈αis␈α
to␈αpartition␈αmemory␈α
such␈αthat␈αparticular␈αportions␈α
of
␈↓ ↓H␈↓the␈α∂address␈α∂space␈α∂correspond␈α∂to␈α∂each␈α∂of␈α∂the␈α∂logical␈α∂spaces:␈α∂atom␈α∂space␈α∂or␈α∂pointer␈α∂space.␈α∂In␈α∂our
␈↓ ↓H␈↓example␈αwe␈αcould␈αassume␈αthat␈αaddresses␈αbelow␈α␈↓
700␈↓␈αare␈αlocations␈αfor␈αpointers,␈αwhile␈αaddresses␈α␈↓
700␈↓
␈↓ ↓H␈↓and␈α⊂above␈α⊂contain␈α⊃atoms.␈α⊂Thus␈α⊂the␈α⊃representation␈α⊂of␈α⊂␈↓α762711␈↓␈α⊂would␈α⊃appear␈α⊂in␈α⊂a␈α⊃location␈α⊂with
␈↓ ↓H␈↓address ␈↓
700␈↓ or greater.
␈↓ ↓H␈↓Though␈α∪our␈α∪memory␈α∪system␈α∪is␈α∪not␈α∪completed␈α∪yet,␈α∪we␈α∪␈↓↓do␈↓␈α∪have␈α∪enough␈α∪structure␈α∪to␈α∀begin␈α∪a
␈↓ ↓H␈↓discussion of the implementation of some of the primitive LISP operations.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓What problems do you foresee in using the double-linking scheme for representing LISP's S-exprs?
␈↓ ↓H␈↓␈↓ ∧I␈↓↓5.3 Representation of LISP Primitives␈↓
␈↓ ↓H␈↓Now␈α
that␈αwe␈α
have␈α
some␈αof␈α
the␈αrepresentational␈α
problems␈α
for␈αS-exprs␈α
reasonably␈αwell␈α
in␈α
hand␈αwe
␈↓ ↓H␈↓will␈αlook␈α
at␈αthe␈α
implementation␈αof␈αthe␈α
LISP␈αprimitives.␈α
We␈αwill␈αexamine␈α
␈↓αcar,␈αcdr,␈α
eq,␈↓␈αand␈α
␈↓αatom␈↓␈αin
␈↓ ↓H␈↓this section, leaving ␈↓αcons␈↓ for later.
␈↓ ↓H␈↓We␈α
must␈α
understand␈α
how␈α
these␈α
primitives␈α
obtain␈αtheir␈α
parameters␈α
and␈α
how␈α
they␈α
are␈α
to␈αreturn␈α
their
␈↓ ↓H␈↓values.␈α∂ Recall␈α∂our␈α∂discussion␈α∂of␈α∞environments␈α∂and␈α∂destinations␈α∂in␈α∂Section 4.6.␈α∂ An␈α∞environment
␈↓ ↓H␈↓chain␈α
was␈α
constructed␈αby␈α
linking␈α
destination␈αblocks␈α
whose␈α
value␈α
slots␈αhave␈α
been␈α
filled.␈αA␈α
dest-block
␈↓ ↓H␈↓was␈αcreated␈αwhen␈αwe␈αrecognized␈αa␈αfunction␈αapplication␈↓π 157␈↓.␈α The␈αname␈αcomponents␈αof␈αa␈α
block␈αare
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 156␈↓ The vertical bar doesn't appear in the machine's memory.
␈↓ ↓H␈↓␈↓π 157␈↓␈α∩If␈α∩the␈α⊃application␈α∩supplied␈α∩an␈α∩incorrect␈α⊃number␈α∩of␈α∩arguments␈α⊃no␈α∩dest-block␈α∩is␈α∩built;␈α⊃the
␈↓ ↓H␈↓debugging␈αroutine␈α
is␈αcalled.␈αSeveral␈α
existing␈αimplementations␈αsupply␈α
missing␈αarguments␈α
with␈α␈↓αNIL␈↓
␈↓ ↓H␈↓or␈αevaluate␈αand␈αdiscard␈αextra␈αarguments.␈αThis␈αtreatment␈αof␈αimproper␈αcalling␈αsequences␈αignores␈αone
␈↓ ↓H␈↓of the most common sources of bugs in LISP programs ([Mot 76]).
␈↓ ↓H␈↓␈↓↓230 static structure␈↓ 45.3␈↓
␈↓ ↓H␈↓either␈α
the␈α
λ-variables␈α
in␈α
the␈α
case␈α
of␈α
a␈α
λ-application␈α
or␈α
are␈α
system-generated␈α
names␈α
in␈α
the␈α∞case␈α
of
␈↓ ↓H␈↓primitive␈α∩application;␈α⊃the␈α∩value-slots␈α∩of␈α⊃a␈α∩dest-block␈α∩received␈α⊃the␈α∩evaluated␈α∩actual␈α⊃parameters.
␈↓ ↓H␈↓When␈αa␈αdest-block␈αwas␈αfilled,␈αit␈αwas␈αchained␈αonto␈αthe␈αfront␈αof␈αthe␈αenvironment␈αand␈αwe␈αwere␈αready
␈↓ ↓H␈↓to␈α
call␈α
the␈αfunction.␈α
Thus␈α
the␈αfirst␈α
block␈α
on␈α
the␈αenvironment␈α
chain␈α
was␈αthe␈α
local␈α
symbol␈αtable.␈α
The
␈↓ ↓H␈↓function␈α∩was␈α∩expected␈α∩to␈α∩return␈α∩its␈α∩value␈α∩to␈α∩a␈α∩designated␈α∩dest-block,␈α∩and␈α∩then␈α∩return␈α∩to␈α∩the
␈↓ ↓H␈↓interrupted␈αcomputation.␈α So,␈αon␈αentrance␈αto␈αa␈αprimitive␈αwe␈αhave␈αaccess␈αto␈αat␈αleast␈αtwo␈αstructures:␈αa
␈↓ ↓H␈↓destination block and the environment chain.
␈↓"␈↓ ↓H␈↓
␈↓αdest␈↓
␈↓αenv␈↓
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααα⊃ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%α→ ~ #αβα⊃ %αα→ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # # # #
␈↓"␈↓ ↓H␈↓
~ ~ ~←$ ~ ~ ~
␈↓"␈↓ ↓H␈↓
εαααβαααλ εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~ ~ ~ ~
␈↓"␈↓ ↓H␈↓
# # # %ααα∀ααα$
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓ ↓H␈↓Here is how ␈↓αcar␈↓ uses these structures:
␈↓ ↓H␈↓␈↓ αhLet␈α␈↓αval␈↓␈αbe␈αthe␈αvalue-part␈αof␈αthe␈αfirst␈αentry␈αin␈αthe␈αlocal␈αtable.␈αIf␈α␈↓αval␈↓␈αis␈αan␈αatom␈αthen␈α␈↓αcar␈↓
␈↓ ↓H␈↓␈↓ αhis␈αundefined;␈αthe␈αimplementation␈αshould␈αsend␈αa␈αmessage␈αto␈αthe␈αdebugging␈αpackage␈α
(see
␈↓ ↓H␈↓␈↓ αhSection 6.23).␈α If␈α␈↓αval␈↓␈αis␈α␈↓↓not␈↓␈αatomic,␈αit␈αhas␈αa␈αleft-␈αand␈αright-hand␈αside.␈α We␈αshould␈αsend
␈↓ ↓H␈↓␈↓ αhthe ␈↓↓left␈↓-hand side of ␈↓αval␈↓ to the value part of the slot pointed to in the dest-block.
␈↓ ↓H␈↓␈↓↓5.3␈↓ π#Representation of LISP Primitives 231␈↓
␈↓ ↓H␈↓For example:
␈↓"␈↓ ↓H␈↓
␈↓αdest␈↓
␈↓αenv␈↓
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααα⊃ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ #αβα⊃ %→ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ ~102~
␈↓"␈↓ ↓H␈↓
~ ~ ~←$ %ααα∀ααα$
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~
␈↓"␈↓ ↓H␈↓
# # #
␈↓"␈↓ ↓H␈↓
εαααβαααλ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
~ ~ ~ 102 ~204~ 22~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$
␈↓"␈↓ ↓H␈↓↓␈↓ ε%Before
␈↓"␈↓ ↓H␈↓
⊂ααααααα⊃ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
~ #αβα⊃ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ ~102~
␈↓"␈↓ ↓H␈↓
~ ~204~←$ %ααα∀ααα$
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~
␈↓"␈↓ ↓H␈↓
# # #
␈↓"␈↓ ↓H␈↓
εαααβαααλ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
~ ~ ~ 102 ~204~ 22~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$
␈↓ ↓H␈↓↓␈↓ ε,After
␈↓ ↓H␈↓↓␈↓ ¬bExample for ␈↓αcar␈↓↓
␈↓ ↓H␈↓For␈αsuccessful␈α
completion␈α␈↓
␈↓αcar␈↓␈α
expects␈αits␈α
actual␈αparameter␈αto␈α
be␈αpointing␈α
to␈αa␈α
node␈αin␈αpointer␈α
space;
␈↓ ↓H␈↓otherwise␈α∞we␈α∞get␈α∞an␈α
error.␈α∞If␈α∞the␈α∞operation␈α
is␈α∞successful␈α∞then␈α∞the␈α
dest-slot␈α∞is␈α∞changed␈α∞to␈α∞point␈α
to
␈↓ ↓H␈↓whatever␈α⊃was␈α⊃pointed␈α⊃to␈α⊃by␈α⊃the␈α⊃left-hand␈α⊃side␈α⊃of␈α⊃the␈α⊃selected␈α⊃cell.␈α⊃ The␈α⊃description␈α⊃of␈α∩␈↓αcdr␈↓␈α⊃is
␈↓ ↓H␈↓sufficiently similar that we leave it to the reader.
␈↓ ↓H␈↓␈↓↓232 static structure␈↓ 45.3␈↓
␈↓ ↓H␈↓On␈αpage 229␈αwe␈αdescribed␈αthe␈αinternal␈α
structure␈αof␈αLISP␈αatoms.␈αUsing␈αthat␈αrepresentation␈α
we␈αcan
␈↓ ↓H␈↓give a simple implementation for the predicate ␈↓αatom␈↓:
␈↓ ↓H␈↓␈↓ αhDoes␈αthe␈αactual␈αparameter␈αpoint␈αinto␈αthat␈αarea␈αreserved␈αfor␈αatom␈αnames?␈αIf␈αso,␈αsend␈αa
␈↓ ↓H␈↓␈↓ αhrepresentation of truth as value, otherwise send a representation of false.
␈↓"␈↓ ↓H␈↓
␈↓αdest␈↓
␈↓αenv␈↓
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααα⊃ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ #αβα⊃ %→ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ ~710~
␈↓"␈↓ ↓H␈↓
~ ~ ~←$ %ααα∀ααα$
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
# # # 710 ~ "A"~
␈↓"␈↓ ↓H␈↓
εαααβαααλ %ααααααα$
␈↓"␈↓ ↓H␈↓
~ ~ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ 714 ~ "T"~
␈↓"␈↓ ↓H␈↓
%ααααααα$
␈↓"␈↓ ↓H␈↓
␈↓We are writing ␈↓
"A"␈↓ instead of the numeric encoding. Thus ␈↓
"A"␈↓ is really ␈↓
40␈↓.␈↓
␈↓"␈↓ ↓H␈↓↓␈↓ ε%Before
␈↓"␈↓ ↓H␈↓
⊂ααααααα⊃ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
~ #αβα⊃ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ ~710~
␈↓"␈↓ ↓H␈↓
~ ~714~←$ %ααα∀ααα$
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~
␈↓"␈↓ ↓H␈↓
# # #
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ ~ ~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓ ↓H␈↓↓␈↓ ε,After
␈↓ ↓H␈↓↓␈↓ ¬XExample for ␈↓αatom␈↓↓
␈↓ ↓H␈↓Notice␈αthat␈αwe␈αdid␈αnot␈αneed␈αto␈αexamine␈αthe␈αcontents␈αof␈αlocation␈α␈↓
710␈↓;␈αit␈αwas␈αsufficient␈αto␈αknow␈αthat
␈↓ ↓H␈↓the␈α∞location␈α
was␈α∞between␈α
predetermined␈α∞bounds.␈α∞ If␈α
the␈α∞actual␈α
parameter␈α∞was␈α
not␈α∞pointing␈α∞at␈α
an
␈↓ ↓H␈↓atom we would have returned a pointer to a location containing ␈↓
"NIL"␈↓.
␈↓ ↓H␈↓␈↓↓5.3␈↓ π#Representation of LISP Primitives 233␈↓
␈↓ ↓H␈↓Finally we describe an implementation of ␈↓αeq␈↓.
␈↓ ↓H␈↓␈↓ αhDo␈α∞both␈α∂actual␈α∞parameters␈α∞point␈α∂into␈α∞atom␈α∞space?␈α∂ If␈α∞not␈α∞the␈α∂result␈α∞is␈α∂undefined.␈α∞If
␈↓ ↓H␈↓␈↓ αhthey␈α␈↓↓do␈↓␈αthen␈αdo␈αthey␈αreference␈αthe␈αsame␈αatom?␈α We␈αcan␈αdetermine␈αthis␈αlatter␈αcondition
␈↓ ↓H␈↓␈↓ αhin␈αtwo␈αways:␈αfirst,␈αthey␈αmight␈αpoint␈αto␈αtwo␈αdifferent␈αlocations␈αin␈αatom␈αspace;␈αwe␈αwould
␈↓ ↓H␈↓␈↓ αhhave␈αto␈αexamine␈αthe␈αcontents␈αof␈αthose␈αlocations;␈αif␈αthey␈αagreed␈αthen␈α␈↓αeq␈↓␈αshould␈αreturn␈αa
␈↓ ↓H␈↓␈↓ αhrepresentation␈α
of␈α
truth.␈α
A␈α
more␈α
satisfactory␈α
solution␈α
is␈α
to␈α
store␈α
each␈α
atom␈α␈↓↓uniquely␈↓;␈α
one
␈↓ ↓H␈↓␈↓ αhlocation␈αwill␈αbe␈αreserved␈αfor␈α
␈↓
"A"␈↓,␈αetc.␈αNow␈αall␈α␈↓αeq␈↓␈αneed␈α
do␈αis␈αmake␈αsure␈αthat␈α
both␈αslots
␈↓ ↓H␈↓␈↓ αhpoint␈α⊂into␈α⊂atom␈α⊂space␈α∂␈↓↓and␈↓␈α⊂point␈α⊂to␈α⊂the␈α∂same␈α⊂location.␈α⊂Thus␈α⊂no␈α⊂additional␈α∂memory
␈↓ ↓H␈↓␈↓ αhreference is required. From now on we will require that all atoms are stored uniquely.
␈↓"␈↓ ↓H␈↓
␈↓αdest␈↓
␈↓αenv␈↓
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααα⊃ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ #αβα⊃ %→ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ ~710~
␈↓"␈↓ ↓H␈↓
~ ~ ~←$ εαααβαααλ
␈↓"␈↓ ↓H␈↓
εαααβαααλ ~ ~710~
␈↓"␈↓ ↓H␈↓
~ ~ ~ %ααα∀ααα$
␈↓"␈↓ ↓H␈↓
# # # ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
εαααβαααλ 714 ~ "T"~
␈↓"␈↓ ↓H␈↓
~ ~ ~ %ααααααα$
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
710 ~ "A"~
␈↓"␈↓ ↓H␈↓
%ααααααα$
␈↓"␈↓ ↓H␈↓↓␈↓ ε%Before
␈↓"␈↓ ↓H␈↓
⊂ααααααα⊃ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
~ #αβα⊃ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ ~710~
␈↓"␈↓ ↓H␈↓
~ ~714~←$ εαααβαααλ
␈↓"␈↓ ↓H␈↓
εαααβαααλ ~ ~710~
␈↓"␈↓ ↓H␈↓
~ ~ ~ %ααα∀ααα$
␈↓"␈↓ ↓H␈↓
# # # ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
εαααβαααλ 714 ~ "T"~
␈↓"␈↓ ↓H␈↓
~ ~ ~ %ααααααα$
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
710 ~ "A"~
␈↓"␈↓ ↓H␈↓
%ααααααα$
␈↓ ↓H␈↓↓␈↓ ε,After
␈↓ ↓H␈↓↓␈↓ ¬iExample for ␈↓αeq␈↓↓
␈↓ ↓H␈↓We␈α
still␈αhave␈α
a␈α
representational␈αproblem␈α
to␈α
resolve:␈αif␈α
we␈α
wish␈αto␈α
represent␈α
the␈αnumber␈α
␈↓α40␈↓␈α
as␈α␈↓
40␈↓
␈↓ ↓H␈↓then␈α∪we␈α∪have␈α∪a␈α∪conflict␈α∪with␈α∪our␈α∩proposed␈α∪representation␈α∪of␈α∪the␈α∪atom␈α∪␈↓αA␈↓␈α∪as␈α∪␈↓
40␈↓.␈α∩Section 5.6
␈↓ ↓H␈↓resolves this conflict.
␈↓ ↓H␈↓␈↓↓234 static structure␈↓ 15.4␈↓
␈↓ ↓H␈↓␈↓ ¬o␈↓↓5.4 AMBIT/G␈↓
␈↓ ↓H␈↓Before␈α
looking␈α
more␈α∞deeply␈α
into␈α
the␈α∞implementation␈α
of␈α
atoms,␈α∞we␈α
should␈α
explore␈α∞possibilities␈α
for
␈↓ ↓H␈↓describing␈αLISP's␈αprimitives.␈α We␈αhave␈αdescribed␈αthem␈α
by␈αexample,␈αwithout␈αmuch␈αloss␈αin␈αclarity.␈α
It
␈↓ ↓H␈↓would␈αbe␈αmore␈αpleasing␈αif␈αwe␈αcould␈αdescribe␈αeach␈αprimitive␈αin␈αmore␈αgeneral␈αterms.␈α Fortunately␈αwe
␈↓ ↓H␈↓can␈α∞give␈α∞less␈α∞machine-dependent␈α∞characterizations␈α∞using␈α∞a␈α∞micro-version␈α∞of␈α∞a␈α∞graphical␈α
language
␈↓ ↓H␈↓called AMBIT/G␈↓π 158␈↓.
␈↓ ↓H␈↓When␈α
faced␈αwith␈α
explaining␈α
a␈αcomplex␈α
structure-manipulating␈α
program,␈αwe␈α
draw␈α
pictures.␈αIn␈α
LISP
␈↓ ↓H␈↓we␈α∞frequently␈α∞describe␈α
data␈α∞structures␈α∞graphically␈α
and␈α∞in␈α∞the␈α
previous␈α∞section␈α∞we␈α∞gave␈α
graphical
␈↓ ↓H␈↓descriptions␈αof␈α
the␈αLISP␈αprimitives␈α
using␈αexamples.␈α
AMBIT␈αis␈αan␈α
extension␈αof␈α
both␈αof␈αthese␈α
ideas;
␈↓ ↓H␈↓it is a graphical language for the description of both data and algorithms.
␈↓ ↓H␈↓The␈α∩basic␈α∩statements␈α∩of␈α∪the␈α∩language␈α∩are␈α∩␈↓↓pattern-match-and-replacement␈↓␈α∩rules.␈α∪ Patterns␈α∩are
␈↓ ↓H␈↓described␈αas␈αcombinations␈αof␈αshapes␈αand␈αsolid␈αarrows.␈α If␈αan␈αinstance␈αof␈αa␈αpattern␈αcan␈αbe␈αfound␈αin
␈↓ ↓H␈↓the␈α
current␈α
state␈α
of␈α
the␈α
computation,␈α
then␈α∞we␈α
will␈α
replace␈α
that␈α
instance␈α
with␈α
a␈α
new␈α∞pattern.␈α
The
␈↓ ↓H␈↓only␈α
kind␈α
of␈αreplacement␈α
we␈α
will␈α
allow␈αis␈α
the␈α
␈↓↓swinging␈↓␈αof␈α
an␈α
arrow␈α
so␈αthat␈α
its␈α
head␈α
moves␈αfrom
␈↓ ↓H␈↓one␈αnode␈αto␈αanother.␈α
Thus␈αthe␈αnew␈αpattern␈αdiffers␈α
from␈αthe␈αold␈αonly␈α
in␈αthe␈αpositioning␈αof␈αsome␈α
of
␈↓ ↓H␈↓the␈αarrows.␈α Where␈αthe␈αarrow␈αhead␈αstrikes␈αa␈αnode␈αis␈αimmaterial;␈αthe␈αorigin␈αof␈αthe␈αtail␈α␈↓↓is␈↓␈αimportant.
␈↓ ↓H␈↓Dashed␈α⊃arrows␈α⊂show␈α⊃replacements␈α⊂to␈α⊃be␈α⊃made␈α⊂if␈α⊃the␈α⊂pattern␈α⊃matches.␈α⊂ Portions␈α⊃of␈α⊃the␈α⊂shapes
␈↓ ↓H␈↓marked with "?" are "don't-care" conditions.
␈↓ ↓H␈↓For example, here's ␈↓αcar␈↓:
␈↓"␈↓ ↓H␈↓
␈↓αdest␈↓
␈↓αenv␈↓
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααα⊃ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ #αβα⊃ %→ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ ~ # ~
␈↓"␈↓ ↓H␈↓
~ ~ ~←$ %ααα∀αβα$
␈↓"␈↓ ↓H␈↓
~ ~ # → - - - - → ~
␈↓"␈↓ ↓H␈↓
εαααβαααλ ↓ ↓
␈↓"␈↓ ↓H␈↓
~ ~ ~ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
# # # | ~ # ~ ? ~
␈↓"␈↓ ↓H␈↓
εαααβαααλ %αβα∀ααα$
␈↓"␈↓ ↓H␈↓
~ ~ ~ ↓ ↓
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%→ - - → - - →~ ? ~
␈↓"␈↓ ↓H␈↓
%ααααααα$
␈↓ ↓H␈↓↓␈↓ ¬\algorithm for ␈↓αcar␈↓↓
␈↓ ↓H␈↓This␈α∞AMBIT␈α∞diagram␈α∞contains␈α∞equivalent␈α∞information␈α∂to␈α∞the␈α∞previous␈α∞␈↓↓example␈↓␈α∞of␈α∞␈↓αcar␈↓,␈α∂but␈α∞the
␈↓ ↓H␈↓extraneous␈α⊃details␈α⊃of␈α⊃specific␈α⊃addresses␈α⊃have␈α⊂been␈α⊃stripped␈α⊃away.␈α⊃ We␈α⊃will␈α⊃use␈α⊃such␈α⊂diagrams
␈↓ ↓H␈↓occasionally when they will contribute to clarity.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 158␈↓␈α⊗An␈α⊗ambit␈α⊗is␈α⊗half␈α⊗aminal,␈α⊗half␈α⊗hobbit.␈α⊗AMBIT/G␈α⊗also␈α⊗is␈α⊗an␈α⊗acronym␈α↔for␈α⊗Algebraic
␈↓ ↓H␈↓Manipulation By Identity Transformation/Graphical.
␈↓ ↓H␈↓␈↓↓5.4␈↓ rAMBIT/G 235␈↓
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓Give an AMBIT diagram for ␈↓αeq␈↓.
␈↓ ↓H␈↓␈↓ ∧S␈↓↓5.5 A Few Programming Techniques␈↓
␈↓ ↓H␈↓There␈αare␈α
a␈αfew␈αuseful␈α
and␈αpractical␈αLISP␈α
programming␈αtechniques␈αwhich␈α
take␈αadvantage␈α
of␈αthe
␈↓ ↓H␈↓implementation.␈α
These␈α
tricks␈α∞are␈α
supported␈α
in␈α
most␈α∞implementations␈α
and␈α
are␈α
useful␈α∞enough␈α
that
␈↓ ↓H␈↓they should be documented as programming language features.
␈↓ ↓H␈↓␈↓↓1.␈↓␈α⊃In␈α⊃most␈α⊃implementations␈α⊃of␈α⊃␈↓αeq␈↓␈α⊃the␈α⊃check␈α⊃for␈α⊃atom-ness␈α⊃is␈α⊃suppressed␈α⊃and␈α⊃a␈α⊃simple␈α⊃address
␈↓ ↓H␈↓␈↓ α_comparison␈α
is␈α
made.␈α
Non-atomic␈α
S-expressions␈α∞are␈α
not␈α
usually␈α
stored␈α
uniquely␈↓π 159␈↓;␈α∞Thus␈α
in
␈↓ ↓H␈↓␈↓ α_most implementations
␈↓ ↓H␈↓␈↓ ∧\␈↓αeq[(A . B);(A . B)]␈↓ is usually false, but
␈↓ ↓H␈↓␈↓ ¬β␈↓αeq[x;x] ␈↓is usually true for any ␈↓αx␈↓.
␈↓ ↓H␈↓␈↓ α_We␈α
are␈α
␈↓↓not␈↓␈α
changing␈α
the␈α
definition␈α
of␈α
␈↓αeq␈↓.␈α
it␈α
is␈α
still␈α
undefined␈α
for␈α
non-atomic␈α
arguments.␈α
The
␈↓ ↓H␈↓␈↓ α_preceding remarks deal only with the usual implementation of ␈↓αeq␈↓.
␈↓ ↓H␈↓␈↓↓2.␈↓␈αThe␈αimplementation␈αof␈αthe␈αtruth␈αvalues␈α␈↓
t␈↓␈α
and␈α␈↓
f␈↓␈αis␈αusually␈αsimplified,␈αmapping␈α␈↓
f␈↓␈αonto␈α
␈↓αNIL␈↓,␈αbut
␈↓ ↓H␈↓␈↓ α_allowing anything ␈↓↓but␈↓ ␈↓αNIL␈↓ as a representation of ␈↓
t␈↓. This allows several related tricks:
␈↓ ↓H␈↓␈↓ ∧≤any expression may be used as a predicate, and
␈↓ ↓H␈↓␈↓ βhused as a predicate, ␈↓αnot[null[l]]␈↓ has the same effect as ␈↓αl␈↓.
␈↓ ↓H␈↓␈↓ α_For␈α∃example,␈α∃consider␈α∃the␈α∃following␈α∃extended␈α∃version␈α∃of␈α∃the␈α∃predicate␈α∃␈↓αmember␈↓.␈α∃ This
␈↓ ↓H␈↓␈↓ α_"predicate",␈α␈↓αmem␈↓λ'␈↓,␈α
will␈αreturn␈α␈↓
f␈↓␈α
if␈αno␈αmatching␈α
element␈αis␈αfound,␈α
otherwise␈αit␈αwill␈α
return␈αthe
␈↓ ↓H␈↓␈↓ α_list beginning at the match; that non-empty list can be used as an indication of truth.
␈↓ ↓H␈↓αmem␈↓λ'␈↓α <= λ[[x;l]␈↓ β_[null[l] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ β_ equal[x;first[l]] → l;
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → mem␈↓λ'␈↓α[x;rest[l]]] ]
␈↓ ↓H␈↓␈↓↓3.␈↓␈α∞Several␈α∂implementations␈α∞of␈α∂conditional␈α∞expressions␈α∞allow␈α∂"p␈↓βi␈↓"␈α∞as␈α∂an␈α∞abbreviation␈α∂for␈α∞"p␈↓βi␈↓ → p␈↓βi␈↓".
␈↓ ↓H␈↓␈↓ α_The computational effect is the same, but p␈↓βi␈↓ is only evaluated once.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 159␈↓ See the problem on hash consing on page 267.
␈↓ ↓H␈↓␈↓↓236 static structure␈↓ 35.5␈↓
␈↓ ↓H␈↓Using this feature, ␈↓αmem␈↓λ'␈↓ could be written:
␈↓ ↓H␈↓αmem␈↓λ'␈↓α <= λ[[x;l]␈↓ β_[null[l] → ␈↓
f␈↓α;
␈↓ ↓H␈↓α␈↓ β_ equal[x;first[l]] → l;
␈↓ ↓H␈↓α␈↓ β_ mem␈↓λ'␈↓α[x;rest[l]]] ]
␈↓ ↓H␈↓This␈α
feature␈α
is␈α
more␈α
useful␈α
in␈α
contexts␈α
where␈α
we␈αwish␈α
to␈α
test␈α
for␈α
the␈α
existence␈α
of␈α
an␈α
object␈α
and,␈αif␈α
a
␈↓ ↓H␈↓match␈αis␈αfound,␈αdo␈αsomething␈αwith␈αthe␈αobject.␈α Applications␈αof␈α␈↓αassoc␈↓␈αoccur␈αin␈αsimilar␈αcontexts.␈α For
␈↓ ↓H␈↓example, the trick of page 198 could be written:
␈↓ ↓H␈↓α␈↓ β8␈↓ βx[cont ← isspec[fun;spectbl];
␈↓ ↓H␈↓α␈↓ β8␈↓ βx isprim[] → ...; ...]
␈↓ ↓H␈↓α␈↓where:␈↓α
␈↓ ↓H␈↓αisspec <= λ[[x;l]␈↓ β8[null[l] → ( );
␈↓ ↓H␈↓α␈↓ β8 eq[name[first[l]];x] → value[first[l]];
␈↓ ↓H␈↓α␈↓ β8 isspec[x;rest[l]]]]
␈↓ ↓H␈↓We␈αcan␈αreturn␈αthe␈αresult␈αof␈α␈↓αvalue␈↓␈αdirectly␈αwithout␈αany␈αproblem,␈αsince␈αthat␈αresult␈αwill␈αbe␈αa␈αfunction
␈↓ ↓H␈↓name and never ␈↓
f␈↓; therefore there will be no ambiguity in using the result of ␈↓αisspec␈↓ as a predicate.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓I.␈α
The␈αapplication␈α
of␈αthese␈α
tricks␈αtends␈α
to␈αlead␈α
to␈αsomewhat␈α
unesthetic␈αprograms.␈α
Typically␈αwe␈α
have
␈↓ ↓H␈↓to␈α∩test␈α∩for␈α∩existence␈α∪then,␈α∩assuming␈α∩an␈α∩instance␈α∩was␈α∪discovered,␈α∩we␈α∩have␈α∩to␈α∪perform␈α∩further
␈↓ ↓H␈↓computation on that instance␈↓π 160␈↓. Constructs like:
␈↓ ↓H␈↓α␈↓ ¬ [it ← test[object] → smash[it]; ...]
␈↓ ↓H␈↓arise.␈αThe␈αobjectional␈αaspect␈αinvolves␈αthe␈αvariable␈α␈↓αit␈↓.␈αThe␈αvariable␈α␈↓αit␈↓␈αis␈αnot␈αlocal␈αto␈αthe␈α
conditional
␈↓ ↓H␈↓expression.␈α∪Either␈α∪␈↓αit␈↓␈α∪is␈α∪global:␈α∪an␈α∪unnecessarily␈α∪gratuitious␈α∪side-effect;␈α∪or␈α∪␈↓αit␈↓␈α∪is␈α∪bound␈α∪by␈α∪an
␈↓ ↓H␈↓enclosing␈α∂λ-expression␈α∞or␈α∂a␈α∞␈↓αprog␈↓.␈α∂ In␈α∞either␈α∂case␈α∂the␈α∞binding␈α∂is␈α∞too␈α∂far␈α∞removed␈α∂from␈α∂its␈α∞usage.
␈↓ ↓H␈↓Sussman and Steele [Sus 76] suggest the construct:
␈↓ ↓H␈↓␈↓ ∧V␈↓αtest[<form␈↓β1␈↓>; ␈↓αλ[[x] ␈↓<form␈↓β2␈↓>]; <form␈↓β3␈↓>],
␈↓ ↓H␈↓with␈α∂the␈α∂following␈α∂semantics:␈α∂evaluate␈α∂<form␈↓β1␈↓>;␈α∂if␈α∂it␈α∂gives␈α∂a␈α∂value␈α∂other␈α∂than␈α∂␈↓
f␈↓␈α∂then␈α∂apply␈α∂the
␈↓ ↓H␈↓second argument, a unary function, to that value. Otherwise evaluate <form␈↓β3␈↓>.
␈↓ ↓H␈↓Recast the ␈↓αisspec␈↓-argument of page 198 in terms of ␈↓αtest␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 160␈↓ If no further computation is necessary, trick No. ␈↓↓3␈↓ suffices.
␈↓ ↓H␈↓␈↓↓5.6␈↓ π7Symbol Tables and Property-lists 237␈↓
␈↓ ↓H␈↓Give an implementation of ␈↓αtest␈↓ by extending one of our evaluators.
␈↓ ↓H␈↓␈↓ ∧S␈↓↓5.6 Symbol Tables and Property-lists␈↓
␈↓ ↓H␈↓Since␈αwe␈αare␈α
looking␈αat␈αimplementation␈αdetails,␈α
and␈αsince␈αmanipulation␈αof␈α
symbol␈αtables␈αis␈α
such␈αa
␈↓ ↓H␈↓central␈α∞issue␈α∞in␈α∂evaluation,␈α∞we␈α∞should␈α∂look␈α∞more␈α∞closely␈α∞at␈α∂symbol␈α∞tables␈α∞and␈α∂their␈α∞organization.
␈↓ ↓H␈↓We␈α
have␈α
seen␈α
two␈α
fundamentally␈α∞different␈α
symbol␈α
table␈α
organizations:␈α
deep␈α
binding␈α∞and␈α
shallow
␈↓ ↓H␈↓binding.␈α∂We␈α∞should␈α∂examine␈α∂the␈α∞implications␈α∂of␈α∞these␈α∂organizations,␈α∂and␈α∞probe␈α∂deeper␈α∂into␈α∞the
␈↓ ↓H␈↓details␈α∂of␈α∞their␈α∂implementation.␈α∞ If␈α∂the␈α∞number␈α∂of␈α∞entries␈α∂associated␈α∞with␈α∂an␈α∞atom␈α∂is␈α∂small␈α∞then
␈↓ ↓H␈↓shallow␈α
binding␈α
may␈α
be␈α
advantageous.␈α
If␈α
the␈α∞number␈α
of␈α
entries␈α
associated␈α
with␈α
an␈α
atom␈α∞is␈α
very
␈↓ ↓H␈↓large␈α⊃then␈α⊃the␈α⊂shallow␈α⊃binding␈α⊃technique␈α⊃may␈α⊂be␈α⊃too␈α⊃costly␈α⊃and␈α⊂deep␈α⊃binding␈α⊃or␈α⊃yet␈α⊂another
␈↓ ↓H␈↓organization may be required ([McD 75]).
␈↓ ↓H␈↓Recall␈α∩our␈α∩discussion␈α∩of␈α⊃␈↓αgetval␈↓,␈α∩␈↓αaddval␈↓,␈α∩and␈α∩␈↓αgetval_cell␈↓␈α⊃in␈α∩Section 3.11.␈α∩ These␈α∩functions␈α⊃were
␈↓ ↓H␈↓developed␈αto␈α
describe␈αshallow␈α
binding,␈αbut␈αthey␈α
are␈αillustrative␈α
of␈αa␈αmore␈α
general␈αidea.␈α
In␈αsymbol
␈↓ ↓H␈↓manipulation␈αand␈αsymbolic␈αprogramming,␈αwe␈α
often␈αwant␈αto␈αbe␈αable␈α
to␈αassociate␈αa␈αset␈αof␈α
data␈αwith
␈↓ ↓H␈↓an␈α∞item.␈α∂For␈α∞example,␈α∂an␈α∞algebraic␈α∞simplifier␈α∂would␈α∞like␈α∂to␈α∞know␈α∞whether␈α∂a␈α∞specific␈α∂operator␈α∞is
␈↓ ↓H␈↓commutative;␈α
if␈α∞so,␈α
certain␈α∞simplifications␈α
are␈α∞valid.␈α
We␈α
could␈α∞maintain␈α
a␈α∞list␈α
of␈α∞all␈α
commutative
␈↓ ↓H␈↓operations␈αand␈αrequire␈αthat␈αthe␈αsimplifier␈αcheck␈αthat␈αlist.␈αBut␈αsince␈αcommutativity␈αis␈αa␈αproperty␈αof
␈↓ ↓H␈↓the␈α_operator␈α↔it␈α_seems␈α↔more␈α_natural␈α↔to␈α_associate␈α↔the␈α_property␈α↔with␈α_the␈α_operation.␈α↔Search
␈↓ ↓H␈↓considerations also arise if the list of operations is long.
␈↓ ↓H␈↓We␈α∂generalize␈α∞the␈α∂idea␈α∂expressed␈α∞in␈α∂␈↓αgetval␈↓␈α∂and␈α∞␈↓αaddval␈↓,␈α∂allowing␈α∂the␈α∞association␈α∂of␈α∂an␈α∞arbitrary
␈↓ ↓H␈↓collection␈αof␈α␈↓¬property-value␈↓␈αpairs␈αwith␈αan␈αatom.␈α With␈αeach␈αatom␈αwe␈αwill␈αassociate␈αa␈αlist␈αcalled␈αthe
␈↓ ↓H␈↓␈↓¬property-list␈↓␈αor␈α␈↓↓p-list␈↓␈↓π 161␈↓.␈α The␈αnames,␈α␈↓↓attribute␈↓␈αor␈α␈↓↓indicator␈↓,␈αare␈αsometimes␈αused␈αas␈αsynonyms␈αfor
␈↓ ↓H␈↓property. An atom is frequently called a ␈↓↓carrier␈↓ of the properties.
␈↓ ↓H␈↓A␈α∂property␈α∞list␈α∂is␈α∞a␈α∂table␈α∞of␈α∂properties␈α∞and␈α∂property values.␈α∞The␈α∂size␈α∞of␈α∂the␈α∞property␈α∂list␈α∂is␈α∞not
␈↓ ↓H␈↓fixed, but can shrink and grow during a computation.
␈↓"␈↓ ↓H␈↓
⊂αααααααπααααα⊃
␈↓"␈↓ ↓H␈↓
~ prop1 ~ val1~
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ
␈↓"␈↓ ↓H␈↓
~ prop2 ~ val2~
␈↓"␈↓ ↓H␈↓
# # #
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ
␈↓"␈↓ ↓H␈↓
~ propn ~ valn~
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααααα$
␈↓ ↓H␈↓We␈α∞have␈α∂seen␈α∞an␈α∂identical␈α∞diagram␈α∂in␈α∞Section 2.4;␈α∞property␈α∂lists␈α∞turn␈α∂out␈α∞to␈α∂be␈α∞a␈α∂very␈α∞effective
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 161␈↓␈α≡Property␈α≥lists␈α≡were␈α≥introduced␈α≡to␈α≡programming␈α≥languages␈α≡in␈α≥the␈α≡IPL␈α≡series␈α≥of
␈↓ ↓H␈↓languages [New 61].
␈↓ ↓H␈↓␈↓↓238 static structure␈↓ 45.6␈↓
␈↓ ↓H␈↓means␈α⊗of␈α⊗modelling␈α⊗data␈α⊗bases␈↓π 162␈↓.␈α↔ As␈α⊗abstractions,␈α⊗property␈α⊗lists␈α⊗are␈α⊗symbol␈α↔tables.␈α⊗The
␈↓ ↓H␈↓name-entries are properties and the value entries are the property values.
␈↓ ↓H␈↓We␈α
identify␈α
an␈α
atom␈α
with␈α
its␈α
property␈αlist.␈α
For␈α
example,␈α
if␈α
we␈α
wished␈α
to␈α
represent␈αthe␈α
"+"-operation
␈↓ ↓H␈↓as␈αthe␈α
atom␈α␈↓αPLUS␈↓␈αand␈α
wished␈αto␈α
signify␈αthat␈αthe␈α
operation␈αis␈αcommutative␈α
and␈αbinary,␈α
the␈αatom
␈↓ ↓H␈↓␈↓αPLUS␈↓ might be represented as:
␈↓"␈↓ ↓H␈↓
PLUS ⊂αααααααπααα⊃
␈↓"␈↓ ↓H␈↓
~ commu ~ T ~
␈↓"␈↓ ↓H␈↓
εαααααααβαααλ
␈↓"␈↓ ↓H␈↓
~ arity ~ 2 ~
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααα$
␈↓ ↓H␈↓In␈α
these␈α
kinds␈α
of␈α
applications,␈αwe␈α
are␈α
using␈α
the␈α
atom␈α
as␈αa␈α
data␈α
structure␈α
and␈α
attaching␈αproperties␈α
to
␈↓ ↓H␈↓that atom rather than thinking of the atom as a representation of an identifier.
␈↓ ↓H␈↓For example:
␈↓"␈↓ ↓H␈↓
CAR ⊂αααααααπααααααα⊃
␈↓"␈↓ ↓H␈↓
~ MFGR ~ BUICK ~
␈↓"␈↓ ↓H␈↓
εαααααααβαααααααλ
␈↓"␈↓ ↓H␈↓
~ YEAR ~ 1959 ~
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααααααα$
␈↓ ↓H␈↓These␈α
same␈α
techniques␈α
are␈α
applicable␈α
when␈α
we␈α
think␈α
about␈α
atoms␈α
as␈α
representations␈α
of␈αvariables␈α
as
␈↓ ↓H␈↓used in the evaluation process.
␈↓ ↓H␈↓In␈αfact,␈αan␈α
atom␈αcan␈αsimultaneously␈α
be␈αused␈αas␈α
a␈αcarrier␈αof␈α
a␈αvalue␈αand␈α
can␈αalso␈αhave␈α
a␈αproperty
␈↓ ↓H␈↓list:
␈↓"␈↓ ↓H␈↓
E4
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
⊂←β X ~ 3 ~
␈↓"␈↓ ↓H␈↓
↓ εαααβαααλ
␈↓"␈↓ ↓H␈↓
# # # E3
␈↓"␈↓ ↓H␈↓
↓ %ααα∀ααα∀→αα→⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
~ # # #
␈↓"␈↓ ↓H␈↓
↓ εαααβαααλ
␈↓"␈↓ ↓H␈↓
%→ααα→π←αα←ααα←β X ~ A ~ E1
␈↓"␈↓ ↓H␈↓
↓ ↑ %ααα∀ααα∀→ααα→⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
⊂αααααααπααααα⊃~ # # #
␈↓"␈↓ ↓H␈↓
~ prop1 ~ val1~~ εαααβαααλ
␈↓"␈↓ ↓H␈↓
# # # %←ααααα←ααααα←ααβ X ~ B ~
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ εαααβαααλ
␈↓"␈↓ ↓H␈↓
~ propn ~ valn~ # # #
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααααα$ %ααα∀ααα$
␈↓"␈↓ ↓H␈↓
␈↓p-list for ␈↓αX␈↓
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 162␈↓ They are by no means the ␈↓↓only␈↓ or ␈↓↓best␈↓ way of representing a data base. See [McD 75].
␈↓ ↓H␈↓␈↓↓5.6␈↓ π7Symbol Tables and Property-lists 239␈↓
␈↓ ↓H␈↓All␈αinstances␈αof␈α␈↓αX␈↓␈αshare␈αa␈αcommon␈αproperty␈αlist,␈αbut␈αthe␈αvalue,␈αor␈αbinding␈αof␈α␈↓αx␈↓␈αis␈αfound␈αusing␈αthe
␈↓ ↓H␈↓environment␈αchain.␈α This␈αexample␈αis␈αdescribed␈αin␈αterms␈αof␈αdeep␈αbinding,␈αbut␈αthe␈αproperty-list␈αidea
␈↓ ↓H␈↓is␈α∂also␈α∂directly␈α∂applicable␈α∂to␈α∂the␈α∂shallow␈α∂binding␈α∂schemes.␈α∂ To␈α∂adapt␈α∂p-lists␈α∂to␈α∂the␈α⊂first␈α∂shallow
␈↓ ↓H␈↓binding␈α
scheme,␈αwe␈α
introduce␈α
a␈αproperty␈α
named␈α
␈↓αVAR␈↓␈αwhose␈α
property␈α
value␈αwill␈α
be␈α
the␈αcollection␈α
of
␈↓ ↓H␈↓environment-value pairs:
␈↓"␈↓ ↓H␈↓
X ⊂αααααααπαααααα⊃ ⊂ααααπααα⊃
␈↓"␈↓ ↓H␈↓
~ VAR ~ #αβα→αα→~ E4 ~ 3 ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααλ εααααβαααλ
␈↓"␈↓ ↓H␈↓
~ prop1 ~ val1 ~ ~ E3 ~ A ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααλ εααααβαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ E1 ~ B ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααλ %αααα∀ααα$
␈↓"␈↓ ↓H␈↓
~ propn ~ valn ~
␈↓"␈↓ ↓H␈↓
%ααααααα∀αααααα$
␈↓ ↓H␈↓Similarly, the second shallow binder could use:
␈↓"␈↓ ↓H␈↓
X ⊂αααααααπαααααα⊃
␈↓"␈↓ ↓H␈↓
~ VALUE ~ #αβα→␈↓<current value>␈↓
␈↓"␈↓ ↓H␈↓
%ααααααα∀αααααα$
␈↓ ↓H␈↓In␈αsummary,␈αproperty␈αlists␈αare␈αa␈αlanguage␈αfeature␈αwhich␈αis␈αindependent␈αof␈αthe␈αbinding␈αstrategy␈αwe
␈↓ ↓H␈↓have␈α
implemented.␈αA␈α
property␈αlist␈α
contains␈αall␈α
the␈α
aspects␈αof␈α
an␈αatom␈α
which␈αwe␈α
wish␈α
to␈αconsider.
␈↓ ↓H␈↓Those␈α∞properties␈α∞need␈α∞not␈α∞involve␈α
the␈α∞fact␈α∞that␈α∞atoms␈α∞are␈α
used␈α∞to␈α∞represent␈α∞identifiers␈α∞when␈α
we
␈↓ ↓H␈↓map␈α
the␈αmeta language␈α
onto␈α
data␈αstructures.␈α
The␈α
deep␈αbinding␈α
implementation␈α
emphasizes␈αthat␈α
the
␈↓ ↓H␈↓value␈α∞of␈α∞a␈α∂variable␈α∞is␈α∞associated␈α∞with␈α∂the␈α∞environment␈α∞in␈α∞which␈α∂that␈α∞value␈α∞is␈α∂created.␈α∞However
␈↓ ↓H␈↓shallow␈α∞binding␈α∂organization␈α∞associates␈α∂values␈α∞with␈α∂variables,␈α∞and␈α∞thus␈α∂it␈α∞is␈α∂natural␈α∞to␈α∂think␈α∞of
␈↓ ↓H␈↓property-lists when thinking of shallow binding.
␈↓ ↓H␈↓We␈αwish␈αto␈αlook␈αmore␈αclosely␈αat␈αthe␈αvalue␈αaspects␈αof␈αatoms.␈α We␈αhave␈αseen␈αthree␈αproperties␈αrelated
␈↓ ↓H␈↓to␈αthe␈αvalue␈α
of␈αa␈αvariable:␈α
simple␈αvalue,␈αcall-by-value␈α
function␈α(expr)␈αand␈αcall-unevaluated␈α
function
␈↓ ↓H␈↓(fexpr).␈αWe␈αwere␈αable␈αto␈αdistinguish␈αbetween␈αexprs␈αand␈αfexprs␈αby␈αone␈αof␈αtwo␈αmethods:␈αeither␈αplace
␈↓ ↓H␈↓the␈αfexpr␈αname␈αin␈αa␈αspecial␈αlist␈αor␈αstore␈αthe␈αfexpr␈αas␈αa␈αβ-expression,␈αrather␈αthan␈αas␈αa␈αλ-expression.
␈↓ ↓H␈↓We␈α⊂made␈α⊂no␈α⊂explicit␈α⊃distinction␈α⊂between␈α⊂simple␈α⊂values␈α⊂and␈α⊃function␈α⊂values;␈α⊂if␈α⊂a␈α⊃simple␈α⊂value
␈↓ ↓H␈↓appeared␈α∂in␈α⊂the␈α∂function␈α∂position␈α⊂of␈α∂an␈α∂application,␈α⊂we␈α∂evaluated␈α∂that␈α⊂expression␈α∂until␈α⊂we␈α∂␈↓↓did␈↓
␈↓ ↓H␈↓discover␈αa␈αfunction␈αobject.␈α If␈αa␈αfunction␈αappeared␈αin␈αa␈αposition␈αexpecting␈αa␈αsimple␈αvalue,␈αthen␈αthe
␈↓ ↓H␈↓data structure interpretation of the function object was taken.
␈↓ ↓H␈↓Since␈α"<="␈αand␈α"<␈↓βf␈↓="␈αwere␈αdefined␈αto␈αplace␈αthe␈αappropriate␈αfunction␈αdefinition␈αin␈αthe␈α
global␈αtable,
␈↓ ↓H␈↓we␈α
can␈α
interpret␈α
these␈α
operations␈α
as␈α
associating␈α
the␈α
definition␈α
with␈α
the␈α
atom.␈α
That␈α
is,␈α
being␈αan␈α
expr
␈↓ ↓H␈↓or␈αfexpr␈αis␈αa␈αproperty␈αof␈αthe␈αatom.␈αSimilarly,␈αglobally␈αbound␈αvariables␈αlike␈α␈↓αt␈↓␈αand␈α␈↓αnil␈↓␈αplay␈αthe␈αroles
␈↓ ↓H␈↓of␈α∞constants␈α∞and␈α∞therefore␈α∞can␈α∞be␈α∞interpreted␈α∞as␈α∞having␈α∞a␈α∞value␈α∞associated␈α∞with␈α∞them.␈α∞Primitive
␈↓ ↓H␈↓functions␈αlike␈α␈↓αcar␈↓,␈αand␈αprimitive␈αspecial␈αforms␈αlike␈α␈↓αcond␈↓␈αshould␈αalso␈αbe␈αconsidered␈αconstants.␈αTheir
␈↓ ↓H␈↓"values" are fixed procedures for specific call-by-value and call-unevaluated operations, respectively.
␈↓ ↓H␈↓␈↓↓240 static structure␈↓ 45.6␈↓
␈↓ ↓H␈↓This␈αdiscussion␈αexemplifies␈αfive␈αvalue-like␈αproperties␈αwhich␈αare␈αproperties␈αof␈αan␈αatom,␈αrather␈αthan
␈↓ ↓H␈↓properties of a particular environment␈↓π 163␈↓:
␈↓ ↓H␈↓␈↓ β(␈↓αCONST␈↓␈↓ πλsimple value; used as a constant
␈↓ ↓H␈↓␈↓ β(␈↓αEXPR␈↓␈↓ πλcall-by value definition
␈↓ ↓H␈↓␈↓ β(␈↓αFEXPR␈↓␈↓ πλcall-unevaluated definition
␈↓ ↓H␈↓␈↓ β(␈↓αSUBR␈↓␈↓ πλcall-by-value primitive
␈↓ ↓H␈↓␈↓ β(␈↓αFSUBR␈↓␈↓ πλcall-unevaluated primitive
␈↓ ↓H␈↓In␈α∂Section 6.19␈α∂we␈α⊂will␈α∂introduce␈α∂another␈α⊂protocol␈α∂for␈α∂assigning␈α∂values␈α⊂to␈α∂variables,␈α∂but␈α⊂at␈α∂any
␈↓ ↓H␈↓one time an atom may have at most one of these value-related indicators␈↓π 164␈↓.
␈↓ ↓H␈↓For example, ␈↓αcar␈↓ might be represented as:
␈↓"␈↓ ↓H␈↓
⊂ααααααπααα⊃
␈↓"␈↓ ↓H␈↓
~ SUBR ~ #αβ→␈↓To machine language code for ␈↓αcar␈↓
␈↓"␈↓ ↓H␈↓
%αααααα∀ααα$
␈↓ ↓H␈↓␈↓ ∧a␈↓↓Part of the atom-structure for ␈↓αCAR␈↓
␈↓ ↓H␈↓When␈α∞we␈α∞use␈α∞␈↓αcar␈↓␈α∞as␈α∞a␈α∞function␈α∞the␈α
machine-dependent␈α∞code␈α∞will␈α∞be␈α∞executed.␈α∞When␈α∞we␈α∞use␈α
the
␈↓ ↓H␈↓atom ␈↓αCAR␈↓ we access the representation ␈↓
CAR␈↓.
␈↓ ↓H␈↓Notice␈α∂that␈α∂each␈α∂indicator␈α∞is␈α∂atomic,␈α∂so␈α∂when␈α∞we␈α∂write␈α∂␈↓
SUBR␈↓␈α∂we␈α∞actually␈α∂mean␈α∂a␈α∂pointer␈α∂to␈α∞the
␈↓ ↓H␈↓representation of the atom ␈↓αSUBR␈↓. Every use of an atom is a reference to its atomic structure.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 163␈↓␈α↔We␈α⊗will␈α↔discuss␈α⊗the␈α↔␈↓αVAR␈↓␈α⊗and␈α↔␈↓αVALUE␈↓␈α⊗properties␈α↔later.␈α⊗ That␈α↔will␈α⊗be␈α↔the␈α↔intent␈α⊗of
␈↓ ↓H␈↓Section 5.19.
␈↓ ↓H␈↓␈↓π 164␈↓␈α∃Several␈α∃implementations␈α∃allow␈α∃atoms␈α∃to␈α∃have␈α∃several␈α∃of␈α∃these␈α∃system␈α∃properties.␈α∃Thus
␈↓ ↓H␈↓expressions␈αlike␈α␈↓αcar[car]␈↓␈αare␈αexecutable.␈αThe␈αimplementation␈αuses␈αcontext␈αto␈αdetermine␈αwhich␈α␈↓αcar␈↓␈αis
␈↓ ↓H␈↓a␈αsimple␈α
variable␈αand␈α
which␈α␈↓αcar␈↓␈α
is␈αthe␈α
primitive␈αprocedure.␈α
The␈αcurrent␈α
␈↓αeval␈↓␈α␈↓↓will␈↓␈αoperate␈α
correctly
␈↓ ↓H␈↓on␈α∂this␈α∞example␈α∂since␈α∞a␈α∂recognizer␈α∞for␈α∂the␈α∂function␈α∞␈↓αcar␈↓␈α∂is␈α∞explicitly␈α∂encoded␈α∞in␈α∂␈↓αapply␈↓,␈α∂but␈α∞such
␈↓ ↓H␈↓tricks␈α∃lead␈α∀to␈α∃unnecessarily␈α∀mysterious␈α∃programs.␈α∃ For␈α∀the␈α∃same␈α∀reason,␈α∃the␈α∃LISP␈α∀obscenity
␈↓ ↓H␈↓␈↓αλ[[lambda]␈α
...␈α
]␈↓␈α
will␈αwork.␈α
Notice␈α
its␈α
S-expr␈αrepresentation␈α
is␈α
␈↓α(LAMBDA (LAMBDA) ␈α
... )␈↓.␈αContext␈α
is
␈↓ ↓H␈↓used␈αby␈αan␈αevaluator␈αin␈αslightly␈αless␈αobnoxious␈αways.␈αFor␈αexample,␈αan␈αevaluator␈αfor␈α␈↓αprog␈↓␈αcan␈αtell␈αa
␈↓ ↓H␈↓reference␈α⊃to␈α⊃the␈α⊃label␈α⊃␈↓αx␈↓␈α∩from␈α⊃the␈α⊃␈↓αprog␈↓-variable␈α⊃␈↓αx␈↓␈α⊃in␈α∩␈↓α ... prog[[x;y] .. x f[..] ... g[x .. ] ... go[x].␈↓␈α⊃See
␈↓ ↓H␈↓page 174.
␈↓ ↓H␈↓␈↓↓5.6␈↓ π7Symbol Tables and Property-lists 241␈↓
␈↓ ↓H␈↓As a further example, we might define:
␈↓ ↓H␈↓␈↓ ∧⊗␈↓αfact <= λ[[x][x=0 → 1; ␈↓
t␈↓α → times[x;fact[sub1[x]]]]]
␈↓ ↓H␈↓α␈↓The S-expr translation of the right-hand side would be:
␈↓ ↓H␈↓α␈↓ β((LAMBDA (X) (COND␈↓ ¬h((ZEROP X) 1)
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬h(T (TIMES␈↓ π_X
␈↓ ↓H␈↓α␈↓ β(␈↓ ¬h␈↓ π_(FACT (SUB1 X))))))
␈↓ ↓H␈↓To␈α
represent␈α
the␈αintention␈α
that␈α
␈↓αfact␈↓␈αis␈α
to␈α
be␈α
defined␈αas␈α
the␈α
above␈αrecursive␈α
function,␈α
we␈αmight␈α
store
␈↓ ↓H␈↓the␈α
S-expr␈α
representation␈α
on␈α
the␈α
property-list␈α
of␈α
the␈α
atom␈α
␈↓αFACT␈↓␈α
and␈α
use␈α
␈↓αEXPR␈↓␈α
as␈α∞its␈α
indicator.
␈↓ ↓H␈↓The␈α∞occurrence␈α∞of␈α∞the␈α∞atom␈α∞␈↓αFACT␈↓␈α∞in␈α∞the␈α
λ-expression␈α∞is␈α∞represented␈α∞as␈α∞a␈α∞pointer␈α∞to␈α∞the␈α
atomic
␈↓ ↓H␈↓structure of ␈↓
FACT␈↓.
␈↓ ↓H␈↓Here is part of the atom-structure for ␈↓αFACT␈↓:
␈↓"␈↓ ↓H␈↓
⊂ααααααπαααα⊃
␈↓"␈↓ ↓H␈↓
FACT ~ EXPR ~ #αβ→⊃
␈↓"␈↓ ↓H␈↓
⊂αα→%αααααα∀αααα$ ~
␈↓"␈↓ ↓H␈↓
↑ ⊂←αααα←ααααα←αα$
␈↓"␈↓ ↓H␈↓
~ %→⊂ααααααααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ ~ LAMBDA ~ #αβαα→~ # ~ #αβα→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
~ %αααααααα∀ααα$ %αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↑ ~ ↓
␈↓"␈↓ ↓H␈↓
~ ⊂αααααααααα$ ⊂ααααααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ ↓ ~ COND ~ #αβ→~ # ~ #αβ→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
~ ⊂αααπαα⊃ %αααααα∀ααα$ %αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↑ ~ X ~≤'~ ↓ ↓
␈↓"␈↓ ↓H␈↓
~ %ααα∀αα$ ... ...
␈↓"␈↓ ↓H␈↓
~ ↓
␈↓"␈↓ ↓H␈↓
~ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
↑ ~ # ~ #αβ→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
~ %αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
%←αααα←αααααα←αααααααα←αααααααα←αααααααα←ααααααα←$ ↓
␈↓"␈↓ ↓H␈↓
⊂←αααααα←αααα$
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
⊂ααααααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ SUB1 ~ #αβ→~ X ~≤'~
␈↓"␈↓ ↓H␈↓
%αααααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓␈↓ ¬#␈↓↓Atom-structure for ␈↓αFACT␈↓
␈↓ ↓H␈↓Note␈α∩that␈α∩both␈α∩instances␈α∩of␈α∩␈↓
X␈↓␈α∩are␈α∩actually␈α∩pointers␈α∩to␈α∩the␈α∩representation␈α∩of␈α∩␈↓αX␈↓,␈α∩but␈α∩that␈α∩two
␈↓ ↓H␈↓representations␈α∞of␈α∞␈↓α(X)␈↓␈α∞will␈α∞typically␈α∞be␈α∞distinct.␈α∞ Also␈α
keep␈α∞in␈α∞mind␈α∞that␈α∞we␈α∞are␈α∞storing␈α∞the␈α
data
␈↓ ↓H␈↓structure ␈↓↓representation␈↓ of the ␈↓αfact␈↓ function.
␈↓ ↓H␈↓␈↓ αT␈↓α(LAMBDA (X) (COND ((ZEROP X) 1) (T (TIMES X (FACT (SUB1 X))))))
␈↓ ↓H␈↓is␈αa␈αperfectly␈αgood␈αlist.␈α If␈αwe␈αattached␈αit␈αto␈αthe␈αindicator␈α␈↓αVALUE␈↓␈αthen␈αwe␈αwould␈αhave␈αrepresented
␈↓ ↓H␈↓the list as the ␈↓↓simple␈↓ value of ␈↓αfact␈↓.
␈↓ ↓H␈↓␈↓↓242 static structure␈↓ 45.6␈↓
␈↓ ↓H␈↓Representations␈α
of␈α
special␈αforms␈α
like␈α
␈↓αCOND␈↓␈αand␈α
␈↓αQUOTE␈↓␈α
give␈α
rise␈αto␈α
the␈α
indicator␈α␈↓αFSUBR␈↓.␈α
When
␈↓ ↓H␈↓an␈α⊃instance␈α⊃of␈α⊂such␈α⊃a␈α⊃special␈α⊂form␈α⊃is␈α⊃recognized,␈α⊂the␈α⊃argument␈α⊃list␈α⊂is␈α⊃passed␈α⊃to␈α⊃the␈α⊂primitive
␈↓ ↓H␈↓without␈αany␈αevaluation.␈α In␈αa␈αsimilar␈αmanner␈αwe␈αintroduce␈αthe␈αindicator␈α␈↓αFEXPR␈↓␈αto␈αdesignate␈αthe
␈↓ ↓H␈↓occurrence of a "<␈↓βf␈↓=" definition.
␈↓ ↓H␈↓Our␈α∪discussion␈α∩of␈α∪property␈α∩lists␈α∪as␈α∩carriers␈α∪of␈α∩values␈α∪has␈α∩centered␈α∪on␈α∩the␈α∪representations␈α∩of
␈↓ ↓H␈↓constants.␈α∞Many␈α
identifiers␈α∞in␈α
LISP␈α∞tend␈α∞to␈α
be␈α∞constants;␈α
even␈α∞though␈α
we␈α∞can␈α∞redefine␈α
functions
␈↓ ↓H␈↓using␈α
a␈α
version␈α
of␈α
"<=",␈α
most␈α∞such␈α
definitions␈α
are␈α
relatively␈α
constant␈↓π 165␈↓.␈α
The␈α∞primitive␈α
functions
␈↓ ↓H␈↓are␈α
also␈α
constant.␈α
Shallow␈α
binding␈α
tries␈α
to␈α
capitalize␈α
on␈α
this␈α
observation,␈α
by␈α
associating␈α
all␈α
of␈αthe
␈↓ ↓H␈↓value␈αaspects␈αof␈αa␈αvariable␈αwith␈αthe␈αproperty␈α
list,␈αand␈αwe␈αwill␈αsoon␈αsee␈αthat␈αfor␈α
several␈αinteresting
␈↓ ↓H␈↓subsets␈αof␈αLISP,␈α
we␈αcan␈αsignificantly␈α
simplify␈αthe␈αhandling␈α
of␈αshallow␈αbinding.␈α
Before␈αdiscussing
␈↓ ↓H␈↓that,␈α∞we␈α∞will␈α∞show␈α∞how␈α∞an␈α∞evaluator␈α
might␈α∞use␈α∞such␈α∞property-list␈α∞information.␈α∞This␈α∞requires␈α
the
␈↓ ↓H␈↓introduction of property-list manipulating functions.
␈↓ ↓H␈↓␈↓ ¬_␈↓↓5.7 Property-list Functions␈↓
␈↓ ↓H␈↓There are four functions for manipulating the property-list:
␈↓ ↓H␈↓␈↓αputprop[a;v;p]␈↓:␈α␈↓αputprop␈↓␈αwill␈αput␈αthe␈αvalue␈α␈↓αv␈↓␈αunder␈αthe␈αproperty␈α␈↓αp␈↓␈αon␈αthe␈αproperty-list␈αof␈αthe␈αatom
␈↓ ↓H␈↓␈↓ β_␈↓αa␈↓.␈α∞If␈α∂the␈α∞property␈α∂␈↓αp␈↓␈α∞already␈α∂appears␈α∞on␈α∂the␈α∞p-list␈α∂then␈α∞the␈α∂␈↓αv␈↓␈α∞over-writes␈α∂the␈α∞old
␈↓ ↓H␈↓␈↓ β_value;␈αotherwise␈αa␈αnew␈αproperty-value␈αpair␈αis␈αadded␈αto␈αthe␈αfront␈αof␈αthe␈αp-list␈α
of␈α␈↓αa␈↓.
␈↓ ↓H␈↓␈↓ β_The value returned by ␈↓αputprop␈↓ is ␈↓αv␈↓␈↓π 166␈↓.
␈↓ ↓H␈↓␈↓αget[x;i]␈↓:␈α␈↓αget␈↓␈αwill␈αsearch␈αthe␈αproperty-list␈αof␈αthe␈αatom␈α␈↓αx␈↓␈αlooking␈αfor␈αthe␈αindicator␈α␈↓αi␈↓.␈αIf␈α␈↓αi␈↓␈αis␈αfound␈αthe
␈↓ ↓H␈↓␈↓ αHvalue␈αassociated␈αwith␈αthat␈αindicator␈αis␈αreturned␈αby␈α␈↓αget␈↓.␈α If␈α␈↓αx␈↓␈αdoes␈αnot␈αhave␈α
the␈αindicator
␈↓ ↓H␈↓␈↓ αHthen ␈↓
f␈↓ is returned. Thus ␈↓αgetval[x]␈↓ could be defined as ␈↓αget[x;VAR].
␈↓ ↓H␈↓␈↓αgetl[x;l]␈↓:␈α⊂␈↓αl␈↓␈α⊂is␈α⊂a␈α⊂list␈α⊃of␈α⊂indicators.␈α⊂ ␈↓αgetl␈↓␈α⊂will␈α⊂search␈α⊂the␈α⊃property-list␈α⊂of␈α⊂the␈α⊂atom␈α⊂␈↓αx␈↓␈α⊂for␈α⊃the␈α⊂␈↓↓first␈↓
␈↓ ↓H␈↓␈↓ αHoccurrence␈α⊂of␈α⊂any␈α⊃indicator␈α⊂which␈α⊂appears␈α⊂in␈α⊃␈↓αl␈↓.␈α⊂ If␈α⊂such␈α⊂a␈α⊃match␈α⊂is␈α⊂found,␈α⊃then␈α⊂the
␈↓ ↓H␈↓␈↓ αH␈↓↓remainder␈↓␈αof␈αthe␈αp-list,␈αbeginning␈αwith␈αthe␈αmatching␈αindicator,␈αis␈αreturned.␈α If␈αno␈αmatch
␈↓ ↓H␈↓␈↓ αHis␈α∞found,␈α∂␈↓
f␈↓␈α∞is␈α∂returned.␈α∞ The␈α∂virtue␈α∞of␈α∞␈↓αgetl␈↓␈α∂is␈α∞that␈α∂it␈α∞can␈α∂distinguish␈α∞between␈α∂an␈α∞atom
␈↓ ↓H␈↓␈↓ αHwhich␈αhas␈α
an␈αindicator␈αwith␈α
value␈α␈↓
f␈↓␈αand␈α
an␈αatom␈α
which␈αdoes␈αnot␈α
have␈αthe␈αindicator.␈α
␈↓αget␈↓
␈↓ ↓H␈↓␈↓ αHcannot␈α
communicate␈α
this␈α
distinction.␈α
The␈α
disadvantage␈α
of␈α
␈↓αgetl␈↓␈α
is␈α
that␈α
it␈α
gives␈α∞access␈α
to
␈↓ ↓H␈↓␈↓ αHthe␈αinternal␈αstructure␈αof␈αthe␈αp-list,␈αand␈αtherefore␈αaccess␈αto␈αthe␈αrepresentation␈αof␈αthe␈αatom.
␈↓ ↓H␈↓␈↓ αHSuch p-list functions are useful but dangerous ([Sam 75]).
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 165␈↓ To define a temporary function we use ␈↓αlabel␈↓.
␈↓ ↓H␈↓␈↓π 166␈↓␈α
In␈α
some␈α
implementations,␈α
the␈α
old␈α
pair␈α
is␈α
removed␈αand␈α
the␈α
new␈α
pair␈α
is␈α
added␈α
to␈α
the␈α
front␈αof␈α
the
␈↓ ↓H␈↓p-list.␈α
The␈α
idea␈α
is␈α
that␈α∞since␈α
short␈α
p-lists␈α
are␈α
usually␈α∞searched␈α
linearly,␈α
one␈α
should␈α
have␈α∞the␈α
most
␈↓ ↓H␈↓popular␈αproperties␈αnear␈αthe␈α
front␈αof␈αthe␈αlist.␈α
This␈αreorganization␈αof␈αthe␈α
table␈αcan␈αeven␈αbe␈α
extended
␈↓ ↓H␈↓to␈αinclude␈α␈↓↓references␈↓␈αto␈αproperties,␈αalways␈αmoving␈αthe␈αlast␈αreferenced␈αproperty␈αpair␈αto␈αthe␈αfront␈αof
␈↓ ↓H␈↓the list [Riv 76].
␈↓ ↓H␈↓␈↓↓5.7␈↓ λAProperty-list Functions 243␈↓
␈↓ ↓H␈↓␈↓αremprop[n;p]␈↓:␈α
The␈αfinal␈α
function␈αin␈α
this␈α
class␈αis␈α
used␈αto␈α
remove␈α
property-value␈αpairs␈α
from␈αthe␈α
p-list
␈↓ ↓H␈↓␈↓ βλof␈α∂an␈α∂atom.␈α⊂The␈α∂function␈α∂is␈α⊂named␈α∂␈↓αremprop␈↓.␈α∂ ␈↓αremprop␈↓␈α⊂has␈α∂two␈α∂arguments:␈α⊂␈↓αn␈↓,␈α∂an
␈↓ ↓H␈↓␈↓ βλatom;␈α∂and␈α∂␈↓αp␈↓,␈α∂a␈α∂property.␈α∞If␈α∂the␈α∂property␈α∂is␈α∂found␈α∞on␈α∂the␈α∂p-list␈α∂of␈α∂the␈α∂atom,␈α∞then
␈↓ ↓H␈↓␈↓ βλ␈↓αremprop␈↓ removes the property-value pair and returns ␈↓
t␈↓; otherwise it returns ␈↓
f␈↓.
␈↓ ↓H␈↓␈↓ ¬⊂␈↓↓5.8 An ␈↓αeval␈↓ for Property-lists␈↓α
␈↓ ↓H␈↓The␈αevaluators␈αin␈αthis␈αsection␈αillustrate␈αthe␈αuse␈αof␈αproperty␈αlists␈αand␈αintroduce␈αthe␈αfirst␈αnon-trivial
␈↓ ↓H␈↓application␈α∂of␈α∂LISP's␈α∂ability␈α⊂to␈α∂interchange␈α∂program␈α∂with␈α⊂data.␈α∂ Though␈α∂this␈α∂chapter␈α⊂is␈α∂mostly
␈↓ ↓H␈↓concerned␈αwith␈αthe␈α␈↓↓static␈↓␈α
organization␈αof␈αLISP,␈αthe␈αideas␈α
involved␈αin␈αthe␈αevaluator␈αare␈α
sufficiently
␈↓ ↓H␈↓important␈αand␈αdemonstrative␈αof␈αthe␈αpower␈αof␈αproperty␈αlists␈αthat␈αwe␈αinclude␈αthem␈αhere␈αrather␈αthan
␈↓ ↓H␈↓later.
␈↓ ↓H␈↓The␈α⊗first␈α⊗evaluator␈α⊗uses␈α∃property␈α⊗names␈α⊗like␈α⊗␈↓αCONST␈↓␈α∃and␈α⊗␈↓αEXPR␈↓␈α⊗as␈α⊗names␈α⊗of␈α∃functions.
␈↓ ↓H␈↓Discovering␈α
that␈α
an␈α
atom␈α
has␈α
the␈α␈↓αCONST␈↓␈α
property,␈α
the␈α
evaluator␈α
␈↓↓applies␈↓␈α
the␈α
function␈αnamed␈α
␈↓αconst␈↓
␈↓ ↓H␈↓to␈α
perform␈α
the␈α
evaluation.␈α
In␈α
this␈α
case,␈α
the␈α
evaluation␈α
is␈α
simple:␈α
return␈α
the␈α
represented␈α
constant.␈α
We
␈↓ ↓H␈↓will␈αassume␈αa␈αshallow␈αbinding␈αimplementation␈αand␈αtherefore␈αvariables␈αare␈αhandled␈αby␈αrecognizing
␈↓ ↓H␈↓the␈αproperty␈α␈↓αVAR␈↓␈αand␈αpassing␈αthe␈αevaluation␈αto␈αthe␈αfunction␈α␈↓αvar␈↓.␈αIn␈αthe␈αcase␈αof␈αan␈αapplication,␈αwe
␈↓ ↓H␈↓have␈α∪more␈α∪work␈α∩to␈α∪do;␈α∪␈↓αexpr␈↓␈α∪handles␈α∩that.␈α∪ The␈α∪actual␈α∩application,␈α∪is␈α∪handled␈α∪using␈α∩LISP's
␈↓ ↓H␈↓computed function facility discussed on page 144.
␈↓ ↓H␈↓We␈α
will␈α
describe␈α
a␈α
sequence␈α
of␈α
evaluators␈αbased␈α
on␈α
property␈α
list␈α
manipulation.␈α
We␈α
will␈αnot␈α
express
␈↓ ↓H␈↓all of the details of this family of evaluators, but leave many of the details to the reader.
␈↓ ↓H␈↓αeval <= λ[[exp;env]␈↓ βX[atom[exp] → form_name[getl[exp;(VAR CONST)]] [exp;env];
␈↓ ↓H␈↓α␈↓ βX atom[first[exp]] → form_name[getl[first[exp];(EXPR FEXPR)]] [exp;env];
␈↓ ↓H␈↓α␈↓ βX ... ]]
␈↓ ↓H␈↓αvar <= λ[[form;env] lookup[form;env]]
␈↓ ↓H␈↓αconst <= λ[[form;env] denote[form;env]]
␈↓ ↓H␈↓αexpr <= λ[[form;env]␈↓ βhλ[[def] eval[␈↓ ¬λbody[def];
␈↓ ↓H␈↓α␈↓ βh␈↓ ¬λmkenv[vars[def];evlist[args[form];env]] ]
␈↓ ↓H␈↓α␈↓ βh [get[func[form];EXPR]]]
␈↓ ↓H␈↓No␈α∞substantial␈α∞benefit␈α∞is␈α∞apparent␈α∞after␈α∞all␈α∞this␈α∞work.␈α∞ With␈α∞a␈α∞slight␈α∞change,␈α∞we␈α∞could␈α∞extract␈α∞a
␈↓ ↓H␈↓small␈α∂improvement.␈α∂Replace␈α∂the␈α∂explicit␈α∂lists␈α∂␈↓α(VAR CONST)␈↓␈α∂and␈α∂␈↓α(EXPR FEXPR)␈↓␈α⊂with␈α∂␈↓αidprop␈↓
␈↓ ↓H␈↓and␈α
␈↓αappprop␈↓.␈α
Bind␈α
these␈α
variables␈α
globally␈α
to␈α
the␈α
respective␈α
lists.␈α
Then␈α
if␈α
we␈α
wished␈α
to␈α
define␈αa
␈↓ ↓H␈↓new␈αkind␈αof␈αcalling␈αsequence,␈α
say␈α␈↓αgexpr␈↓s,␈αwe␈αcould␈αadd␈α
␈↓αGEXPR␈↓␈αto␈α␈↓αappprop␈↓␈αand␈αwrite␈α
a␈αfunction
␈↓ ↓H␈↓named␈α
␈↓αgexpr␈↓␈α
to␈αhandle␈α
the␈α
evaluation␈α
of␈α␈↓αgexpr␈↓␈α
forms.␈α
However␈α
with␈αfurther␈α
analysis,␈α
we␈α
can␈αdo
␈↓ ↓H␈↓much better.
␈↓ ↓H␈↓␈↓↓244 static structure␈↓ 35.8␈↓
␈↓ ↓H␈↓Consider␈α
simple␈αvariables.␈α
Each␈α
instance␈αof␈α
a␈α
simple␈αvariable␈α
has␈α
the␈αsame␈α
value␈α
property;␈αwhen
␈↓ ↓H␈↓we␈αsee␈α␈↓αx␈↓␈α
we␈αapply␈α␈↓αlookup␈↓␈αthrough␈α
␈↓αvar␈↓;␈αwhen␈αwe␈α
see␈α␈↓αy␈↓␈αwe␈αapply␈α
␈↓αlookup␈↓␈αthrough␈α␈↓αvar␈↓.␈α
However␈αthe
␈↓ ↓H␈↓association␈α⊃of␈α⊃a␈α⊃value␈α⊃property␈α⊃with␈α⊃each␈α⊃␈↓↓instance␈↓␈α⊃of␈α⊃a␈α⊃variable␈α⊃is␈α⊃discomforting.␈α∩The␈α⊃value
␈↓ ↓H␈↓property␈αis␈αmore␈αa␈αproperty␈αof␈αthe␈αclass␈αof␈αvariables␈αthan␈αit␈αis␈αa␈αproperty␈αof␈αan␈αinstance.␈α That␈αis,
␈↓ ↓H␈↓an instance receives a property by being a member of a certain class.
␈↓ ↓H␈↓Let␈αthe␈αatom␈α␈↓αVAR␈↓␈αrepresent␈αthe␈αclass␈αof␈αvariables;␈αlet␈αthe␈αatom␈α␈↓αEVAL␈↓␈αrepresent␈αthe␈αproperty␈αname
␈↓ ↓H␈↓describing␈α
value␈α
properties.␈α
The␈αfunction␈α
␈↓αlookup␈↓␈α
is␈α
therefore␈α
a␈αproperty␈α
value␈α
of␈α
the␈α
atom␈α␈↓αVAR␈↓,
␈↓ ↓H␈↓and should be associated with the property name ␈↓αEVAL␈↓.
␈↓"␈↓ ↓H␈↓
X ⊂αααααααπαααααα⊃ ⊂ααααπααα⊃ VAR ⊂ααααααπαααααααα⊃
␈↓"␈↓ ↓H␈↓
~ VAR ~ #αβα→αα→~ E4 ~ 3 ~ ~ EVAL ~ LOOKUP ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααλ εααααβαααλ %αααααα∀αααααααα$
␈↓"␈↓ ↓H␈↓
~ prop1 ~ val1 ~ ~ E3 ~ A ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααλ εααααβαααλ
␈↓"␈↓ ↓H␈↓
# # # ~ E1 ~ B ~
␈↓"␈↓ ↓H␈↓
εαααααααβααααααλ %αααα∀ααα$
␈↓"␈↓ ↓H␈↓
~ propn ~ valn ~
␈↓"␈↓ ↓H␈↓
%ααααααα∀αααααα$
␈↓ ↓H␈↓Now␈αthe␈αevaluator␈αshould␈αdo␈αa␈αdouble␈α␈↓αget␈↓,␈αlooking␈αdown␈αthe␈αproperty␈αlist␈αof␈αan␈αobject,␈αfor␈αa␈αclass
␈↓ ↓H␈↓name␈αwhich␈αhas␈αan␈α␈↓αEVAL␈↓␈αproperty.␈α Finding␈α␈↓αEVAL␈↓,␈αthe␈αevaluator␈αapplies␈αthe␈αassociated␈αproperty
␈↓ ↓H␈↓value to the object and the environment.
␈↓ ↓H␈↓Before␈α
presenting␈α
the␈α
next␈α
evaluator␈α
we␈α
should␈α
settle␈α
one␈α
more␈α
point.␈α
In␈α
the␈α
preceeding␈α
␈↓αeval␈↓␈α
we
␈↓ ↓H␈↓ignored␈α∀the␈α∀question␈α∀of␈α∀anonymous␈α∃λ-expressions;␈α∀we␈α∀assumed␈α∀that␈α∀the␈α∀function-part␈α∃of␈α∀an
␈↓ ↓H␈↓application␈αwas␈αan␈αatom.␈αWe␈αdid␈αthis␈αbecaue␈αwe␈αhave␈αimplied␈αthat␈αonly␈αatoms␈αhave␈αproperty␈αlists.
␈↓ ↓H␈↓We␈α∂will␈α⊂remove␈α∂this␈α∂restriction␈α⊂for␈α∂the␈α⊂next␈α∂evaluator␈α∂and␈α⊂assume␈α∂that␈α∂any␈α⊂object␈α∂can␈α⊂have␈α∂a
␈↓ ↓H␈↓property␈αlist.␈αA␈αλ-expression␈αwill␈αhave␈αa␈αproperty␈αlist␈αwith␈α(at␈αleast)␈αproperty␈αname␈α␈↓αLAMBDA␈↓␈αand
␈↓ ↓H␈↓property␈α
value␈α
of␈α
the␈αrepesentation␈α
of␈α
the␈α
λ-expression.␈α
The␈αatom␈α
␈↓αLAMBDA␈↓␈α
will␈α
have␈α
an␈α␈↓αEVAL␈↓
␈↓ ↓H␈↓property␈α∀whose␈α∃value␈α∀is␈α∀the␈α∃function␈α∀␈↓αeval_λ␈↓;␈α∀this␈α∃function␈α∀will␈α∀evaluate␈α∃applications␈α∀whose
␈↓ ↓H␈↓function-parts are λ-expressions.
␈↓ ↓H␈↓Finally,␈α∞since␈α∞␈↓αeval_λ␈↓␈α∞handles␈α∞most␈α
of␈α∞the␈α∞evaluation␈α∞of␈α∞an␈α
application,␈α∞there␈α∞is␈α∞no␈α∞need␈α∞to␈α
make
␈↓ ↓H␈↓␈↓αexpr␈↓␈α
do␈α
it␈α
too.␈α
In␈α
fact,␈α
our␈α
previous␈α
distinction␈α
between␈α
␈↓αVAR␈↓␈α
and␈α
␈↓αEXPR␈↓␈α
is␈αunnecessarily␈α
restrictive.
␈↓ ↓H␈↓We␈αshould␈α
be␈αable␈αto␈α
return␈αfunctions␈αas␈α
values␈αjust␈αas␈α
we␈αcan␈αreturn␈α
constants␈αor␈α
simple␈αvalues.
␈↓ ↓H␈↓So␈α∂␈↓αEXPR␈↓␈α⊂should␈α∂be␈α∂a␈α⊂property␈α∂name,␈α∂with␈α⊂property␈α∂value␈α∂being␈α⊂the␈α∂λ-expression,␈α⊂but␈α∂␈↓αEXPR␈↓
␈↓ ↓H␈↓should now have an ␈↓αEVAL␈↓ property which is just ␈↓αlookup␈↓.
␈↓ ↓H␈↓␈↓↓5.8␈↓ πiAn %3eval%1 for Property-lists 245␈↓
␈↓ ↓H␈↓For example:
␈↓"␈↓ ↓H␈↓
plist for FACT plist for (LAMBDA (X) (COND ((ZEROP X) ... )))
␈↓"␈↓ ↓H␈↓
⊂ααααααπααα⊃ ⊂ααααααααπααα⊃
␈↓"␈↓ ↓H␈↓
~ EXPR ~ #αβ→ααααα→~ LAMBDA ~ #αβ→αα→ (LAMBDA (X) (COND ((ZEROP X) ...
␈↓"␈↓ ↓H␈↓
εααααααβαααλ εααααααααβαααλ
␈↓"␈↓ ↓H␈↓
# # # # # #
␈↓"␈↓ ↓H␈↓
%αααααα∀ααα$ %αααααααα∀ααα$
␈↓"␈↓ ↓H␈↓
plist for EXPR plist for LAMBDA
␈↓"␈↓ ↓H␈↓
⊂ααααααπαααααααα⊃ ⊂ααααααπααααααααα⊃
␈↓"␈↓ ↓H␈↓
~ EVAL ~ LOOKUP ~ ~ EVAL ~ EVALLAM ~
␈↓"␈↓ ↓H␈↓
εααααααβααααααααλ εααααααβαααααααααλ
␈↓"␈↓ ↓H␈↓
# # # # # #
␈↓"␈↓ ↓H␈↓
%αααααα∀αααααααα$ %αααααα∀ααααααααα$
␈↓ ↓H␈↓With all this extra mechanism in place, ␈↓αeval␈↓ does absolutely nothing!
␈↓ ↓H␈↓α␈↓ ∧⊃eval <= λ[[exp;env] getget[exp;EVAL] [exp;env]],
␈↓ ↓H␈↓where␈α⊂␈↓αgetget␈↓␈α∂looks␈α⊂at␈α⊂property␈α∂names␈α⊂associated␈α⊂with␈α∂␈↓αexp␈↓␈α⊂until␈α∂it␈α⊂finds␈α⊂one␈α∂which␈α⊂itself␈α⊂has␈α∂a
␈↓ ↓H␈↓property list containing ␈↓αEVAL␈↓.
␈↓ ↓H␈↓Now␈α
real␈α
progress␈α
has␈α∞been␈α
made.␈α
The␈α
evaluation␈α
of␈α∞any␈α
expression␈α
is␈α
controlled␈α
by␈α∞a␈α
function
␈↓ ↓H␈↓associated␈αwith␈αthe␈αclass␈αto␈αwhich␈αthat␈αexpression␈αbelongs.␈αIt␈αis␈αtrivial␈αto␈αmodify␈αor␈αextend␈αsuch␈αan
␈↓ ↓H␈↓evaluator: supply the class name and the appropriate ␈↓αEVAL␈↓ property value.
␈↓ ↓H␈↓The␈α∞technique␈α∞is␈α∂applicable␈α∞to␈α∞more␈α∂general␈α∞kinds␈α∞of␈α∞computation␈α∂than␈α∞just␈α∞evaluation.␈α∂With␈α∞a
␈↓ ↓H␈↓class␈α
name␈α
we␈α
can␈α
associate␈α
arbitrary␈α
pairs␈α
of␈α
properties␈α
and␈α
functions.␈α
For␈α
example,␈α
we␈α
might␈α
wish
␈↓ ↓H␈↓to␈α∞define␈α
special␈α∞input␈α∞or␈α
output␈α∞conventions␈α∞for␈α
classes;␈α∞to␈α
do␈α∞this␈α∞we␈α
simply␈α∞associate␈α∞a␈α
␈↓αREAD␈↓
␈↓ ↓H␈↓property␈α
and␈α
a␈α
␈↓αPRINT␈↓␈α
property␈α
with␈α
the␈α∞class␈α
name␈α
and␈α
supply␈α
routines␈α
to␈α
perform␈α∞the␈α
special
␈↓ ↓H␈↓reading␈αor␈αprinting.␈αSimilarly,␈αwe␈αcan␈αassociate␈αa␈αcompile␈αproperty,␈αand␈αa␈αfunction␈αdescribing␈αhow
␈↓ ↓H␈↓to compile instances of this construct␈↓π 167␈↓.
␈↓ ↓H␈↓The␈α⊃net␈α⊃effect␈α⊃of␈α⊂this␈α⊃reworking␈α⊃of␈α⊃evaluation␈α⊂is␈α⊃to␈α⊃expose␈α⊃a␈α⊂much␈α⊃more␈α⊃general␈α⊃scheme␈α⊂for
␈↓ ↓H␈↓handling␈α∃computation.␈α∃ Such␈α∃a␈α∀distributed␈α∃␈↓αeval␈↓␈α∃is␈α∃an␈α∀example␈α∃of␈α∃a␈α∃LISP␈α∃technique␈α∀called
␈↓ ↓H␈↓data-driven programming ([San 75a])␈↓π 168␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 167␈↓␈α⊂The␈α∂language␈α⊂EL1␈α∂([EL1 74])␈α⊂incorporates␈α∂a␈α⊂similar␈α∂scheme,␈α⊂however␈α∂only␈α⊂five␈α∂designated
␈↓ ↓H␈↓properties␈α
can␈α
be␈α
associated␈α
with␈α
any␈αclass␈α
name.␈α
The␈α
techniques␈α
of␈α
syntax-directed␈αinput-output,
␈↓ ↓H␈↓developed in Section 9.4, are also applicable to such an evaluator.
␈↓ ↓H␈↓␈↓π 168␈↓␈α
The␈αauthor␈α
first␈α
saw␈αthis␈α
technique␈α
used␈αin␈α
a␈α
non-trivial␈αway␈α
in␈α
[Dif 71]␈αin␈α
the␈αStanford␈α
LISP
␈↓ ↓H␈↓compiler.
␈↓ ↓H␈↓␈↓↓246 static structure␈↓ 35.8␈↓
␈↓ ↓H␈↓Property␈αlist␈α
representations␈αhve␈αalso␈α
found␈αextensive␈α
use␈αin␈αdata␈α
base␈αapplications␈α(Section 2.4;␈α
see
␈↓ ↓H␈↓[San 75a].
␈↓ ↓H␈↓␈↓ ∧\␈↓↓5.9 Representation of Property-lists␈↓
␈↓ ↓H␈↓In␈α⊂discussing␈α∂representations,␈α⊂we␈α∂must␈α⊂keep␈α∂the␈α⊂essential␈α∂characteristics␈α⊂of␈α∂property␈α⊂lists␈α⊂well␈α∂in
␈↓ ↓H␈↓mind.␈α
A␈α
property␈α
list␈α
is␈α
similar␈α
to␈α
a␈α∞local␈α
environment␈α
block;␈α
each␈α
property␈α
list␈α
is␈α
a␈α∞sequence␈α
of
␈↓ ↓H␈↓names␈α∃and␈α∃values.␈α∃However␈α∀a␈α∃property␈α∃list␈α∃can␈α∀grow␈α∃and␈α∃shrink␈α∃dynamically,␈α∃whereas␈α∀an
␈↓ ↓H␈↓environment␈α
block␈αis␈α
created␈α
at␈αa␈α
fixed␈α
size.␈αSince␈α
we␈α
cannot␈αpredict␈α
the␈α
size␈αof␈α
the␈α
block,␈αa␈α
natural
␈↓ ↓H␈↓representation is that of a list.
␈↓"␈↓ ↓H␈↓
⊂αααααααπααααα⊃
␈↓"␈↓ ↓H␈↓
~ prop1 ~ val1~
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ
␈↓"␈↓ ↓H␈↓
~ prop2 ~ val2~ ⊂αααααααπααα⊃ ⊂αααααπααα⊃ ⊂αααααααπααα⊃ ⊂αααααπαα⊃
␈↓"␈↓ ↓H␈↓
# # # ~ prop1 ~ #αβα→~ val1~ #αβ→ ...→~ propn ~ #αβα→~ valn~≤'~
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ %ααααααα∀ααα$ %ααααα∀ααα$ %ααααααα∀ααα$ %ααααα∀αα$
␈↓"␈↓ ↓H␈↓
~ propn ~ valn~
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααααα$
␈↓"␈↓ ↓H␈↓
␈↓↓Property list Representation␈↓
␈↓ ↓H␈↓The␈α
elements␈α
of␈α
the␈αp-list␈α
are␈α
associated␈α
in␈α
pairs.␈αThe␈α
first␈α
element␈α
of␈αa␈α
pair␈α
is␈α
the␈α
property,␈αthe
␈↓ ↓H␈↓next␈α
element␈α
is␈α
the␈α
property␈α
value.␈α
But␈α
atoms␈α
can't␈α
be␈α
represented␈α
as␈α
just␈α
any␈α
arbitrary␈α
list.␈α
We
␈↓ ↓H␈↓must be able to recognize the occurrence of an atom so that we can implement the predicate ␈↓αatom␈↓.
␈↓ ↓H␈↓There␈α∞are␈α∞at␈α∞least␈α∞two␈α∞alternatives.␈α∞We␈α∞might␈α∞partition␈α∞memory␈α∞as␈α∞we␈α∞began␈α∞to␈α∞do␈α∂on␈α∞page 229
␈↓ ↓H␈↓with␈α∂pointer␈α∂space␈α⊂and␈α∂atom␈α∂space.␈α⊂ Then␈α∂the␈α∂test␈α∂of␈α⊂atom-ness␈α∂is␈α∂a␈α⊂test␈α∂on␈α∂the␈α⊂location␈α∂being
␈↓ ↓H␈↓referenced.␈α∞ We␈α
might␈α∞also␈α
preface␈α∞the␈α
property␈α∞list␈α
with␈α∞an␈α
"atom header"␈α∞which␈α
will␈α∞signal␈α
the
␈↓ ↓H␈↓beginning␈α
of␈α
the␈α
atom.␈α
Here␈α
the␈α
test␈α
for␈α∞atom-ness␈α
is␈α
a␈α
test␈α
on␈α
the␈α
contents␈α
of␈α
the␈α∞location␈α
being
␈↓ ↓H␈↓referenced.␈α
In␈α
the␈α
first␈α
case␈α
we␈α
dedicate␈α
a␈α
section␈α
of␈α
memory␈α
for␈α
the␈α
storage␈α
of␈α
atoms␈↓π 169␈↓;␈α
in␈α
the
␈↓ ↓H␈↓second case we require an extra memory reference.
␈↓ ↓H␈↓A␈α∞related␈α∞efficiency␈α
consideration␈α∞involves␈α∞the␈α
use␈α∞of␈α∞property␈α
lists␈α∞by␈α∞the␈α∞LISP␈α
implementation.
␈↓ ↓H␈↓Since␈αthe␈αevaluator␈αwill␈αbe␈αmaking␈αfrequent␈αexamination␈αof␈αthe␈αp-list,␈αit␈αis␈αoften␈αuseful␈αto␈αstore␈αthe
␈↓ ↓H␈↓system-related␈α⊂information␈α∂in␈α⊂specific␈α⊂relative␈α∂positions␈α⊂of␈α∂the␈α⊂p-list.␈α⊂This␈α∂will␈α⊂obviate␈α⊂a␈α∂search
␈↓ ↓H␈↓using ␈↓αget␈↓.
␈↓ ↓H␈↓Using␈α∂a␈α⊂separate␈α∂"atom␈α⊂space",␈α∂an␈α⊂atom␈α∂would␈α∂be␈α⊂represented␈α∂by␈α⊂its␈α∂property␈α⊂list.␈α∂In␈α⊂this␈α∂case,
␈↓ ↓H␈↓property␈αlists␈αneed␈αnot␈αbe␈αstored␈αin␈αpointer␈αspace.␈αChapter 7␈αexamines␈αsome␈αof␈αthese␈αtechniques.␈αIn
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 169␈↓␈αWe␈αneed␈αnot␈αdedicate␈α
a␈αwhole␈αsection␈αof␈αthe␈α
machine␈αto␈α"atom␈αspace".␈αSeveral␈α
techniques␈αare
␈↓ ↓H␈↓available␈αfor␈α
"mapping"␈αa␈α
conceptually␈αcontiguous␈α
space␈αonto␈α
a␈αscattered␈αmemory.[Ste 73],␈α
[Nor 76],
␈↓ ↓H␈↓[Pre 76a].
␈↓ ↓H␈↓␈↓↓5.9␈↓ πIRepresentation of Property-lists 247␈↓
␈↓ ↓H␈↓the␈αtext␈α
we␈αwill␈αdescribe␈α
atoms␈αusing␈αthe␈α
"atom␈αheader"␈αsince␈α
it␈αmakes␈αit␈α
clearer␈αin␈αpictures.␈α
Atoms
␈↓ ↓H␈↓will␈α⊂be␈α⊂special␈α⊂lists␈α⊃whose␈α⊂␈↓αcar␈↓-part␈α⊂contains␈α⊂an␈α⊂indicator␈α⊃used␈α⊂exclusively␈α⊂for␈α⊂the␈α⊃beginning␈α⊂of
␈↓ ↓H␈↓atoms.␈αWe␈αwill␈αuse␈α␈↓
∃␈↓␈αto␈αdesignate␈αthe␈αbeginning␈αof␈αan␈αatom.␈α The␈α␈↓αcdr␈↓␈αof␈αthe␈αrepresentation␈αof␈αthe
␈↓ ↓H␈↓atom␈αis␈αthe␈αrepresentation␈αof␈αthe␈αproperty␈αlist.␈α
Such␈αlocations␈αin␈αpointer␈αspace␈αcontaining␈α␈↓
∃␈↓␈αin␈α
their
␈↓ ↓H␈↓left-half and a pointer to a p-list in their right-half are called ␈↓↓atom headers␈↓.
␈↓ ↓H␈↓For example, here is part of a representation for the atom for ␈↓αcar␈↓:
␈↓"␈↓ ↓H␈↓
⊂ααπαααα⊃ ⊂ααααααπαααα⊃ ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
~∃ ~ #αβαα→~ SUBR ~ #αβαα→~ # ~ # ...→
␈↓"␈↓ ↓H␈↓
%αα∀αααα$ %αααααα∀αααα$ %αβα∀ααα$
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
%→αα→ to machine code for ␈↓αcar␈↓
␈↓ ↓H␈↓␈↓ ∧a␈↓↓Part of the atom-structure for ␈↓αCAR␈↓
␈↓ ↓H␈↓An␈α∞example␈α∞of␈α∞the␈α∞distinction␈α∞between␈α∞␈↓αget␈↓␈α∞and␈α∞␈↓αgetl␈↓␈α∞in␈α∞our␈α∞representation␈α∞may␈α∞be␈α∂useful.␈α∞Notice
␈↓ ↓H␈↓how both functions allow unnecessarily free access to the internal representation.
␈↓"␈↓ ↓H␈↓
␈↓αgetl[FOO;(BAZ)]␈↓
␈↓"␈↓ ↓H␈↓
⊗
␈↓"␈↓ ↓H␈↓
␈↓αgetl[FOO;(PNARF BAZ)]␈↓
␈↓αget[FOO;PNARF]␈↓
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
⊂ααα←ααααααα$ ~
␈↓"␈↓ ↓H␈↓
⊂απααα⊃ ↓ ⊂αααααπααα⊃ ⊂αααααπααα⊃ ⊂αααααααπααα⊃ ⊂αααπαα⊃ ~
␈↓"␈↓ ↓H␈↓
~∃~ #αβαα→~ BAZ ~ #αβα→~ NIL ~ #αβα→~ PNARF ~ #αβα→~ # ~≤'~ ↓
␈↓"␈↓ ↓H␈↓
%α∀ααα$ %ααααα∀ααα$ %ααααα∀ααα$ %ααααααα∀ααα$ %αβα∀αα$ ~
␈↓"␈↓ ↓H␈↓
ε←ααα←ααα$
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ A ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀αα$
␈↓ ↓H␈↓and ␈↓αget[FOO;BAZ] = get[FOO;BAR] = NIL␈↓.
␈↓ ↓H␈↓The␈αsimple␈αatom␈αis␈α
becoming␈αmuch␈αmore␈αcomplex.␈α
It␈αhas␈αa␈αwhole␈α
substructure␈αattached␈αto␈αit.␈α
Thus
␈↓ ↓H␈↓each␈αatom␈αis␈αlike␈αa␈αword␈αin␈αa␈αdictionary;␈αmany␈αwords␈αcan␈αbe␈αused␈αas␈αdifferent␈αparts␈αof␈αspeech␈αand
␈↓ ↓H␈↓their␈αdictionary␈αentries␈αwill␈α
reflect␈αthis␈αby␈αhaving␈α
several␈αalternative␈αmeanings.␈αSimilarly,␈α
an␈αatom
␈↓ ↓H␈↓can␈α∂have␈α⊂several␈α∂different␈α⊂"meanings"␈α∂attached␈α∂to␈α⊂it␈α∂and␈α⊂depending␈α∂on␈α∂the␈α⊂context,␈α∂we␈α⊂will␈α∂be
␈↓ ↓H␈↓interested␈α
in␈α
one␈α
of␈αthose␈α
interpretations.␈α
Just␈α
as␈αwe␈α
will␈α
find␈α
all␈αmeanings␈α
of␈α
a␈α
specific␈α
word␈αin
␈↓ ↓H␈↓one␈αlocation␈αin␈αthe␈αdictionary,␈αour␈αimplementation␈αof␈αLISP␈αbecomes␈αmuch␈αsimpler␈αif␈αwe␈αstore␈αeach
␈↓ ↓H␈↓atom␈α∞and␈α∞its␈α∞associated␈α∞p-list␈α∞uniquely.␈α∞For␈α∞example,␈α∞every␈α∞reference␈α∞to␈α∞the␈α∞atom␈α∞␈↓αA␈↓␈α∞is␈α∞actually␈α∞a
␈↓ ↓H␈↓pointer␈α∂to␈α∂the␈α∂same␈α∂location␈α∞in␈α∂memory.␈α∂This␈α∂location␈α∂has␈α∞a␈α∂␈↓αcar␈↓-part␈α∂which␈α∂is␈α∂the␈α∂special␈α∞atom
␈↓ ↓H␈↓indicator ␈↓
∃␈↓, and a ␈↓αcdr␈↓-part which is the p-list for the atom ␈↓αA␈↓.
␈↓ ↓H␈↓␈↓↓248 static structure␈↓ 45.9␈↓
␈↓ ↓H␈↓Thus ␈↓α(A . A)␈↓, which we have been representing as:
␈↓"␈↓ ↓H␈↓
⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
~ A ~ A ~
␈↓"␈↓ ↓H␈↓
%ααααα∀ααααα$
␈↓ ↓H␈↓in more detail, is represented as:
␈↓"␈↓ ↓H␈↓
⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
~ # ~ # ~
␈↓"␈↓ ↓H␈↓
%ααβαα∀ααβαα$
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ~ ⊂απααα⊃
␈↓"␈↓ ↓H␈↓
%ααααα∀α→~∃~ #αβα→ ␈↓p-list for ␈↓αA␈↓
.
␈↓"␈↓ ↓H␈↓
%α∀ααα$
␈↓ ↓H␈↓The␈αinternal␈αstructures␈αof␈αthis␈αimplementation␈αof␈αLISP␈αare␈α␈↓↓not␈↓␈αL-trees,␈αbut␈αlist␈αstructure;␈αthere␈αare
␈↓ ↓H␈↓intersecting␈α∞and␈α∞circular␈α∞branches.␈α∞ LISP␈α∞deals␈α
with␈α∞binary␈α∞list␈α∞structure␈α∞since␈α∞each␈α
non-terminal
␈↓ ↓H␈↓node in our representation has exactly two branches.
␈↓ ↓H␈↓Assume␈α
we␈α
have␈α
the␈α
above␈α
dotted␈α
pair␈α
as␈α
a␈α
value␈α
of␈α
a␈α
variable␈α
␈↓αx␈↓␈α
and␈α
we␈α
wish␈α
to␈α
print␈α
the␈α
value␈α
of
␈↓ ↓H␈↓␈↓αx␈↓.␈α Clearly␈αwe␈αwould␈αhope␈αto␈αsee␈α"␈↓α(A␈α.␈αA)␈↓"␈αappear␈αon␈αthe␈αoutput␈αdevice.␈α We␈αwould␈αexpect␈αthat␈αthe
␈↓ ↓H␈↓print␈αroutine,␈αnamed␈α␈↓αprint␈↓,␈αwould␈αbe␈αgiven␈αa␈αpointer␈αto␈αthe␈αdotted␈αpair.␈α␈↓αprint␈↓␈αcan␈αrecognize␈αthat␈αit
␈↓ ↓H␈↓␈↓↓is␈↓␈α∞a␈α∞dotted␈α∂pair␈α∞since␈α∞its␈α∞␈↓αcar␈↓␈α∂is␈α∞not␈α∞␈↓
∃␈↓.␈α∂ But␈α∞how␈α∞can␈α∞␈↓αprint␈↓␈α∂distinguish␈α∞␈↓α(A␈α∞.␈α∞A)␈↓␈α∂from␈α∞␈↓α(B␈α∞.␈α∂B)␈↓␈α∞for
␈↓ ↓H␈↓example?␈αThe␈αpointer␈αin␈αthe␈αpreceding␈αdiagram␈αwill␈αpoint␈αto␈α␈↓αA␈↓␈αin␈αone␈αcase␈αand␈αto␈α␈↓αB␈↓␈αin␈αthe␈αother,
␈↓ ↓H␈↓but␈α∩nothing␈α∪about␈α∩the␈α∪atom␈α∩tells␈α∪us␈α∩␈↓↓what␈↓␈α∪to␈α∩print.␈α∩ The␈α∪simplest␈α∩thing␈α∪to␈α∩do␈α∪is␈α∩to␈α∪store␈α∩a
␈↓ ↓H␈↓representation␈α∞of␈α∞the␈α∞name␈α∞on␈α∞each␈α∞p-list.␈α∞ This␈α∞is␈α∞done␈α∞with␈α∞another␈α∞indicator␈α∂called␈α∞␈↓αPNAME␈↓,
␈↓ ↓H␈↓standing␈α∪for␈α∩␈↓↓print-name␈↓.␈α∪Each␈α∪atom␈α∩is␈α∪guaranteed␈α∩to␈α∪have␈α∪a␈α∩print-name␈α∪or␈α∪"p-name".␈α∩ The
␈↓ ↓H␈↓print-name of the atom is what the LISP output routine will print as the name of the atom.
␈↓ ↓H␈↓The atom ␈↓αBAZ␈↓ will have at least the following␈↓π 170␈↓:
␈↓"␈↓ ↓H␈↓
⊂αααααααπααααααα⊃
␈↓"␈↓ ↓H␈↓
~ PNAME ~ "BAZ" ~
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααααααα$
␈↓ ↓H␈↓Where ␈↓
"BAZ"␈↓ means a representation of the string of characters, ␈↓αB, A, Z␈↓.
␈↓ ↓H␈↓When␈α
we␈α
wish␈αto␈α
␈↓↓represent␈↓␈α
such␈αa␈α
property␈α
pair␈αwe␈α
must␈α
deal␈αwith␈α
representational␈α
problems␈αof
␈↓ ↓H␈↓character␈αstrings.␈α
The␈αsalient␈αproperties␈α
here␈αare␈αthe␈α
desire␈αto␈αhave␈α
strings␈αof␈α
unbounded␈αlength,
␈↓ ↓H␈↓but␈α⊗represent␈α⊗them␈α⊗in␈α⊗a␈α⊗machine␈α⊗with␈α↔fixed␈α⊗word␈α⊗size.␈α⊗We␈α⊗will␈α⊗discuss␈α⊗a␈α↔more␈α⊗general
␈↓ ↓H␈↓representation␈α∪in␈α∀Section 7.3,␈α∪but␈α∪here␈α∀we␈α∪will␈α∪represent␈α∀the␈α∪print␈α∪name␈α∀by␈α∪using␈α∀the␈α∪basic
␈↓ ↓H␈↓dotted-pair data structure of LISP.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 170␈↓␈α∂Since␈α∂␈↓↓every␈↓␈α∂atom␈α∂is␈α∂quaranteed␈α∂to␈α∂have␈α∂a␈α∂print␈α∂name,␈α∂many␈α∂implementations␈α∂separate␈α∂this
␈↓ ↓H␈↓property from the general p-list.
␈↓ ↓H␈↓␈↓↓5.9␈↓ πIRepresentation of Property-lists 249␈↓
␈↓"␈↓ ↓H␈↓
⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
~ BAZ≡≡ ~
␈↓"␈↓ ↓H␈↓
%ααααααα$
␈↓ ↓H␈↓␈↓ ∧z␈↓↓p-name representation for ␈↓αBAZ␈↓.
␈↓ ↓H␈↓␈↓
BAZ≡≡␈↓␈αmeans␈αa␈αmemory␈αlocation␈αcontaining␈αsome␈αencoding␈αof␈αthe␈αletters␈α␈↓
B␈↓,␈α␈↓
A␈↓,␈αand␈α␈↓
Z␈↓.␈α The␈αsymbol,
␈↓ ↓H␈↓␈↓
≡␈↓,␈αrepresents␈αsome␈αnon-printing␈αcharacter;␈αin␈αthe␈αabove␈αdiagram,␈αwe␈αare␈αtherefore␈αassuming␈αthat␈αa
␈↓ ↓H␈↓location can contain five characters.
␈↓ ↓H␈↓We␈α∂represent␈α∞the␈α∂print-name␈α∂as␈α∞a␈α∂list␈α∂so␈α∞that␈α∂we␈α∞may␈α∂allow␈α∂atoms␈α∞with␈α∂p-names␈α∂of␈α∞unbounded
␈↓ ↓H␈↓length. The p-name for ␈↓αBLETCH␈↓, would be:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ # ~ #αβαααα→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
⊂ααααααα⊃ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
~ BLETC ~ ~ H≡≡≡≡ ~
␈↓"␈↓ ↓H␈↓
%ααααααα$ %ααααααα$
␈↓ ↓H␈↓␈↓ ∧{␈↓↓P-name structure for ␈↓αBLETCH␈↓.
␈↓ ↓H␈↓With␈α
such␈α∞print-names␈α
on␈α
each␈α∞property-list␈α
␈↓αprint␈↓␈α
can␈α∞now␈α
operate.␈α
The␈α∞␈↓αprint␈↓␈α
routine␈α∞needs␈α
the
␈↓ ↓H␈↓print␈αname␈αand,␈αas␈αwe␈αshall␈αsee␈αshortly,␈αthe␈αinput␈αroutine␈αalso␈αneeds␈αthe␈αprint␈αname,␈αbut␈αotherwise
␈↓ ↓H␈↓all␈α
LISP␈α∞calculation␈α
is␈α∞done␈α
using␈α∞the␈α
internal␈α∞pointers␈α
to␈α∞the␈α
representation␈α∞of␈α
the␈α∞property␈α
list.
␈↓ ↓H␈↓Several␈α
implementations␈α
exploit␈α
this␈α
observation␈α
by␈α
placing␈α
the␈α
print names␈α
in␈α
slower␈αmemory␈α
than
␈↓ ↓H␈↓that␈α∞used␈α∞for␈α∞the␈α∞main␈α∞computation.␈α∞Since␈α∞access␈α∞to␈α∞print␈α∞names␈α∞is␈α∞infrequent,␈α∞we␈α∞can␈α∂afford␈α∞to
␈↓ ↓H␈↓spend␈αmore␈αtime␈αin␈αretrieving␈α
them.␈α We␈αwill␈αdiscuss␈αmore␈αof␈α
the␈αdetails␈αof␈αLISP␈αinput␈αand␈α
output
␈↓ ↓H␈↓in Section 5.11.
␈↓ ↓H␈↓The␈α
actual␈α
print-names␈α
␈↓
BAZ≡≡␈↓,␈α
␈↓
BLETC␈↓,␈α
and␈α∞␈↓
H≡≡≡≡␈↓,␈α
are␈α
candidates␈α
for␈α
storage␈α
in␈α
atom␈α∞space␈α
since
␈↓ ↓H␈↓these␈α∀encodings␈α∀should␈α∀not␈α∀be␈α∀interpreted␈α∀as␈α∪pointers.␈α∀ Since␈α∀"atom␈α∀space"␈α∀is␈α∀no␈α∀longer␈α∪an
␈↓ ↓H␈↓appropriate␈α
descriptor␈α
for␈αthat␈α
space,␈α
we␈α
will␈αgive␈α
it␈α
a␈αnew␈α
name.␈α
We␈α
will␈αcall␈α
that␈α
area␈αof␈α
memory
␈↓ ↓H␈↓which␈αcontains␈α
information␈α␈↓↓not␈↓␈αto␈α
be␈αinterpreted␈αas␈α
pointers,␈α␈↓↓Full␈αWord␈α
Space␈↓,␈αand␈α
abbreviate␈αit
␈↓ ↓H␈↓as FWS.
␈↓ ↓H␈↓In␈αsummary,␈αwe␈αhave␈αdiscussed␈αthe␈αdetails␈αof␈αa␈αtypical␈αimplementation␈αof␈αthe␈αclass␈αof␈αS-exprs.␈αOur
␈↓ ↓H␈↓non-atomic␈α∞S-exprs␈α∂have␈α∞their␈α∂branching␈α∞structure␈α∂stored␈α∞in␈α∂what␈α∞we␈α∂have␈α∞called␈α∂pointer␈α∞space.
␈↓ ↓H␈↓Our␈α∪initial␈α∪discussion␈α∩of␈α∪atoms␈α∪supposed␈α∩a␈α∪particular␈α∪simple␈α∩representation:␈α∪simply␈α∪store␈α∩the
␈↓ ↓H␈↓encoding␈αof␈αthe␈αatom␈αin␈αa␈αmemory␈αlocation␈αfound␈αin␈αa␈αseparate␈αspace␈αwhich␈αwe␈αcalled␈αatom␈αspace.
␈↓ ↓H␈↓␈↓↓250 static structure␈↓ 45.9␈↓
␈↓ ↓H␈↓Upon␈α→further␈α→reflection␈α→we␈α_decided␈α→that␈α→atoms␈α→should␈α→play␈α_a␈α→more␈α→active␈α→role␈α→in␈α_the
␈↓ ↓H␈↓implementation.␈αSince␈α
identifiers␈αare␈α
to␈αbe␈α
represented␈αas␈αatoms␈α
we␈αneeded␈α
some␈αway␈α
to␈αrepresent
␈↓ ↓H␈↓those␈α∞properties␈α∞typically␈α∞associated␈α∞with␈α∞identifiers.␈α
Identifiers␈α∞in␈α∞LISP␈α∞are,␈α∞among␈α∞other␈α
things,
␈↓ ↓H␈↓used␈α∞for␈α∞names␈α∞of␈α∞functions␈α∞and␈α∞names␈α∞of␈α
variables.␈α∞We␈α∞needed␈α∞the␈α∞ability␈α∞to␈α∞represent␈α∞at␈α
least
␈↓ ↓H␈↓these␈αtwo␈αkinds␈αof␈α"values"␈αwith␈αa␈αLISP␈αatom.␈α We␈αintroduced␈αthe␈αgeneral␈αscheme␈αof␈αproperty-lists
␈↓ ↓H␈↓and␈α
associated␈α
such␈αa␈α
p-list␈α
with␈α
each␈αLISP␈α
atom.␈α
All␈αthe␈α
things␈α
we␈α
know␈αabout␈α
a␈α
specific␈αatom␈α
are
␈↓ ↓H␈↓stored␈αon␈αthe␈αp-list.␈αThus␈αwe␈αwant␈αeach␈αatom␈αstored␈αuniquely;␈αthen␈αanyone␈αwho␈αwants␈αto␈αexamine
␈↓ ↓H␈↓the␈α
properties␈α
of␈α
an␈α
atom␈α
has␈α
only␈α
to␈α
look␈α∞at␈α
the␈α
p-list.␈α
Since␈α
all␈α
of␈α
our␈α
LISP␈α
programs␈α∞must␈α
be
␈↓ ↓H␈↓read␈α
into␈α
the␈α
memory␈α
we␈α
let␈α
the␈α
input␈α
function␈α
keep␈α
track␈α
of␈α
the␈α
details.␈α
On␈α
reading␈α
a␈αliteral␈α
atom,
␈↓ ↓H␈↓the␈αprogram␈αchecks␈αthe␈αcurrent␈αtable␈αof␈αatoms.␈α If␈αthe␈αatom␈αappears,␈αthe␈αprogram␈αreturns␈αa␈α
pointer
␈↓ ↓H␈↓to␈α∞the␈α∞entry.␈α∞ If␈α∞the␈α∞atom␈α
does␈α∞not␈α∞appear␈α∞it␈α∞constructs␈α∞a␈α
new␈α∞table␈α∞entry␈α∞consisting␈α∞of␈α∞the␈α
print
␈↓ ↓H␈↓name.␈α The␈αeffect␈αof␈αstoring␈αatoms␈αuniquely␈αwas␈αto␈αturn␈αour␈αabstract␈αLISP-trees␈αinto␈αlist␈αstructure.
␈↓ ↓H␈↓Indeed,␈αthe␈αrepresentation␈αof␈αa␈αLISP␈αexpression␈α
is␈αa␈αcomplex␈αnet␈αof␈αpointers;␈αeven␈αatoms␈α
are␈αnow
␈↓ ↓H␈↓pointers.␈α∩The␈α∪only␈α∩LISP␈α∪objects␈α∩we␈α∪have␈α∩represented␈α∩which␈α∪are␈α∩␈↓↓not␈↓␈α∪pointers␈α∩are␈α∪the␈α∩actual
␈↓ ↓H␈↓print-names like ␈↓
BAZ≡≡␈↓.
␈↓ ↓H␈↓To␈α∞reinforce␈α∞our␈α∞discussion␈α∞we␈α∞illustrate␈α∞the␈α∞abstract␈α∞picture␈α∞of␈α∞␈↓αNIL␈↓␈α∞and,␈α∞on␈α∞the␈α∞next␈α∞page,␈α
the
␈↓ ↓H␈↓representation␈αof␈αthe␈αatom␈α␈↓αNIL␈↓.␈αIn␈αall␈αof␈αthe␈αresulting␈αworms␈αthere␈αare␈αonly␈αthree␈αelements␈αin␈αFull
␈↓ ↓H␈↓Word Space; everything else is a pointer.
␈↓"␈↓ ↓H␈↓
⊂αααααα→αααααα→ααααααα→αααααα→ααααααα⊃
␈↓"␈↓ ↓H␈↓
↑ ↓
␈↓"␈↓ ↓H␈↓
⊂ααα←ααααα←ααααα⊃ ~
␈↓"␈↓ ↓H␈↓
↓ ↑ ~ ⊂α←α⊃ ↓
␈↓"␈↓ ↓H␈↓
~ ⊂αβαπααααα⊃ ↑ ↓ ⊂αβαπααααααα⊃ ⊂αααπααααααα⊃
␈↓"␈↓ ↓H␈↓
%αα→~ # ~ #α→αβ→$ ε→~ # ~ PNAME ~ ~ # ~ CONST ~
␈↓"␈↓ ↓H␈↓
εαααβαααααλ ↑ %ααα∀ααααααα$ %αβα∀ααααααα$
␈↓"␈↓ ↓H␈↓
~ # ~ NIL ~ %←αααααα←αααααα←ααααα$
␈↓"␈↓ ↓H␈↓
%αβα∀ααααα$ ↑
␈↓"␈↓ ↓H␈↓
%→αααααα→αααααα→$
␈↓ ↓H␈↓␈↓↓5.10␈↓ λ∧A Picture of the Atom ␈↓αNIL␈↓↓ 251␈↓α
␈↓ ↓H␈↓␈↓ ∧s␈↓↓5.10 A Picture of the Atom ␈↓αNIL␈↓↓␈↓α
␈↓ ↓H␈↓We have been writing the atom ␈↓αNIL␈↓ as:
␈↓"␈↓ ↓H␈↓
⊂απααα⊃ ⊂αααααααπααα⊃ ⊂αααπααα⊃ ⊂αααααααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~∃~ #αβα→~ CONST ~ #αβα→~ # ~ #αβα→~ PNAME ~ #αβα→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%α∀ααα$ %ααααααα∀ααα$ %αβα∀ααα$ %ααααααα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ~ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
NIL %α→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
~NIL≡≡~
␈↓"␈↓ ↓H␈↓
%ααααα$
␈↓ ↓H␈↓where the atoms for ␈↓αPNAME␈↓ and ␈↓αCONST␈↓ are represented as:
␈↓"␈↓ ↓H␈↓
⊂απααα⊃ ⊂αααααααπααα⊃ ⊂αααπαα⊃ ⊂απααα⊃ ⊂αααααααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~∃~ #αβα→~ PNAME ~ #αβα→~ # ~≤'~ ~∃~ #αβα→~ PNAME ~ #αβα→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%α∀ααα$ %ααααααα∀ααα$ %αβα∀αα$ %α∀ααα$ %ααααααα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
⊂αααπαα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ # ~≤'~ ~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αβα∀αα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
⊂ααααα⊃ ⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
~PNAME~ ~CONST~
␈↓"␈↓ ↓H␈↓
%ααααα$ %ααααα$
␈↓ ↓H␈↓In full detail, ␈↓αNIL␈↓ is represented as:
␈↓"␈↓ ↓H␈↓
⊂ααααααααααααααααααα←ααααααααααααααααααααααααααα←ααααααπααααπααααααααπααα⊃
␈↓"␈↓ ↓H␈↓
↓ ↑ ~ ↑ ↑
␈↓"␈↓ ↓H␈↓
⊂απααα⊃ ⊂αααααααπααα⊃ ⊂αααπααα⊃ ⊂αααααααπααα⊃ ⊂αααπαβα⊃ ↑ ~ ~
␈↓"␈↓ ↓H␈↓
~∃~ #αβα→~ # ~ #αβα→~ # ~ #αβα→~ # ~ #αβα→~ # ~ # ~ ~ ~ ~
␈↓"␈↓ ↓H␈↓
%α∀ααα$ %αααβααα∀ααα$ %αβα∀ααα$ %αααβααα∀ααα$ %αβα∀ααα$ ~ ~ ~
␈↓"␈↓ ↓H␈↓
↑ %αααααααααα→ ~ →αααααααα→ ~→αα⊃ ~ ↑ ~ ~
␈↓"␈↓ ↓H␈↓
~ ↓ ~ ~ ~ ⊂αααπαβα⊃ ~ ~
␈↓"␈↓ ↓H␈↓
~ ~ ↓ ↓ %α→~ # ~ # ~ ~ ~
␈↓"␈↓ ↓H␈↓
~ ↓ ~ ~ %αβα∀ααα$ ~ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ ~ ↓ ↑ ↑
␈↓"␈↓ ↓H␈↓
%ααααααα←ααααααααα←αααααα∀αααπαααα⊃ ~ ~ ⊂ααααα⊃ ~ ~
␈↓"␈↓ ↓H␈↓
↑ ↑ ~ ~ ~NIL≡≡~ ~ ~
␈↓"␈↓ ↓H␈↓
~ ~ ↓ ~ %ααααα$ ~ ~
␈↓"␈↓ ↓H␈↓
⊂αααααααααα←ααααααααααααααα← ~ ←α ~ ←α$ ~ ~ ~
␈↓"␈↓ ↓H␈↓
↓ ~ ~ ↓ ~ ~
␈↓"␈↓ ↓H␈↓
⊂απααα⊃ ⊂αααααααπααα⊃ ⊂αααπαβα⊃ ~ ⊂απααα⊃ ⊂αααααααπααα⊃ ⊂αααπαβα⊃ ↑
␈↓"␈↓ ↓H␈↓
~∃~ #αβα→~ # ~ #αβα→~ # ~ # ~ ↑ ~∃~ #αβα→~ # ~ #αβα→~ # ~ # ~ ~
␈↓"␈↓ ↓H␈↓
%α∀ααα$ %αααβααα∀ααα$ %αβα∀ααα$ ~ %α∀ααα$ %αααβααα∀ααα$ %αβα∀ααα$ ~
␈↓"␈↓ ↓H␈↓
↑ ~ ↓ ~ ~ ↓ ~
␈↓"␈↓ ↓H␈↓
εααααα←ααααα$ ⊂αααπααα⊃ ↑ ↓ ⊂αααπααα⊃↑
␈↓"␈↓ ↓H␈↓
~ ~ # ~ #αβα$ ~ ~ # ~ #αβ$
␈↓"␈↓ ↓H␈↓
~ %αβα∀ααα$ ~ %αβα∀ααα$
␈↓"␈↓ ↓H␈↓
~ ↓ ~ ↓
␈↓"␈↓ ↓H␈↓
↑ ⊂ααααα⊃ ~ ⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
~ ~PNAME~ ↓ ~CONST~
␈↓"␈↓ ↓H␈↓
~ %ααααα$ ~ %ααααα$
␈↓"␈↓ ↓H␈↓
%αααααααα←ααααααααααααα←ααααααααααααα←αααααααααααααα$
␈↓ ↓H␈↓␈↓↓252 static structure␈↓ *5.11␈↓
␈↓ ↓H␈↓␈↓ ∧k␈↓↓5.11 Input/Output: ␈↓αread␈↓↓ and ␈↓αprint␈↓↓␈↓α
␈↓ ↓H␈↓Any␈α∂implementation␈α∂of␈α∂LISP␈α∂is␈α∂simplified␈α∂dramatically␈α∂since␈α∂a␈α∂very␈α∂large␈α∂part␈α∂of␈α∂LISP␈α∂can␈α∂be
␈↓ ↓H␈↓written␈α
in␈α
LISP␈α∞itself.␈α
We␈α
have␈α
already␈α∞seen␈α
that␈α
the␈α
evaluation␈α∞process␈α
is␈α
expressible␈α∞this␈α
way,
␈↓ ↓H␈↓and we will exploit this property again in dealing with compilers (Chapter 6).
␈↓ ↓H␈↓This␈αthis␈αsection␈αwe␈αwill␈αdiscover␈αthat␈αthe␈αmajority␈αof␈αthe␈αmajority␈αof␈αthe␈αLISP␈αinput␈α
and␈αoutput
␈↓ ↓H␈↓routines␈α∂can␈α∂be␈α∞written␈α∂as␈α∂LISP␈α∂functions␈α∞calling␈α∂a␈α∂very␈α∞few␈α∂primitive␈α∂routines.␈α∂ The␈α∞primitive
␈↓ ↓H␈↓routines are also described in LISP, though they would normally be coded in machine language.
␈↓ ↓H␈↓The primitive functions are ␈↓αratom␈↓ and ␈↓αpatom␈↓.
␈↓ ↓H␈↓␈↓αratom[␈α∂]␈↓␈α∞is␈α∂a␈α∂function␈α∞of␈α∂no␈α∂arguments.␈α∞It␈α∂reads␈α∂the␈α∞input␈α∂string,␈α∂constructing␈α∞the␈α∂next␈α∂atom␈α∞or
␈↓ ↓H␈↓␈↓ αHspecial␈α
character␈α(left␈α
paren,␈αright␈α
paren␈αor␈α
dot).␈α
It␈αlooks␈α
up␈αthat␈α
object␈αin␈α
the␈αatom␈α
table
␈↓ ↓H␈↓␈↓ αHand␈α∞returns␈α∞a␈α
pointer␈α∞to␈α∞that␈α
table␈α∞entry.␈α∞ If␈α
no␈α∞entry␈α∞is␈α
found␈α∞an␈α∞appropriate␈α∞entry␈α
is
␈↓ ↓H␈↓␈↓ αHmade.␈α
␈↓αratom␈↓␈α
flushes␈α
spaces␈α
and␈α
commas,␈α
recognizing␈α
them␈α
as␈α
delimiters.␈α
It␈α
returns␈αonly
␈↓ ↓H␈↓␈↓ αHatoms or special characters to ␈↓αread␈↓.
␈↓ ↓H␈↓␈↓αpatom[x]␈↓␈αis␈αa␈αfunction␈αof␈αone␈αargument␈αexpecting␈αan␈αatom,␈αleft␈αparen,␈αright␈αparen,␈αblank,␈αor␈αdot␈αas
␈↓ ↓H␈↓␈↓ αHthe value of its argument. It will print the p-name of that object on the output device.
␈↓ ↓H␈↓␈↓αratom␈↓␈α⊃is␈α∩the␈α⊃LISP␈α∩␈↓↓scanner␈↓.␈α⊃A␈α∩scanner␈α⊃must␈α∩negotiate␈α⊃with␈α∩the␈α⊃actual␈α∩input␈α⊃device␈α∩for␈α⊃input
␈↓ ↓H␈↓characters.␈α∂The␈α∂scanner␈α∂builds␈α∂the␈α∂most␈α⊂basic␈α∂ingredients,␈α∂like␈α∂identifiers␈α∂or␈α∂numbers,␈α⊂and␈α∂only
␈↓ ↓H␈↓after␈α∞such␈α∞a␈α∞basic␈α∞block␈α
has␈α∞been␈α∞recognized␈α∞is␈α∞the␈α
next␈α∞level␈α∞of␈α∞syntax␈α∞analysis␈α∞attempted.␈α
The
␈↓ ↓H␈↓units, also called tokens, which the scanner has built are passed to the ␈↓↓parser␈↓.
␈↓ ↓H␈↓A␈αparser␈αencodes␈αthe␈αBNF␈αequations␈αof␈αthe␈αclass␈αof␈αwell-formed␈αinput␈αexpressions␈αand␈αdetermines
␈↓ ↓H␈↓whether␈α≤or␈α≤not␈α≤the␈α≤input␈α≤stream␈α≥is␈α≤a␈α≤well-formed␈α≤expression.␈α≤ The␈α≤parser␈α≥builds␈α≤a
␈↓ ↓H␈↓tree-representation␈α⊂of␈α⊂the␈α⊂input␈α⊂string;␈α⊂the␈α⊃structure␈α⊂of␈α⊂the␈α⊂tree␈α⊂reflects␈α⊂the␈α⊃language␈α⊂constructs
␈↓ ↓H␈↓which␈αwere␈αpresent␈αin␈αthe␈α
input.␈α ␈↓αread␈↓␈αis␈αthe␈αLISP␈α
parser;␈αit␈αwill␈αrecognize␈αboth␈α
S-expression␈αand
␈↓ ↓H␈↓list-notation.␈α Besides␈α
analyzing␈αthe␈α
input␈αstream,␈α
␈↓αread␈↓␈αalso␈α
builds␈αan␈α
S-expression␈αrepresentation␈α
of
␈↓ ↓H␈↓the input.
␈↓ ↓H␈↓To␈α
simplify␈αmatters,␈α
we␈αneed␈α
to␈αrefer␈α
to␈αatoms␈α
whose␈αprint-names␈α
are␈αthe␈α
characters␈α"␈↓α)␈↓",␈α
"␈↓α(␈↓",␈α".",␈α
and
␈↓ ↓H␈↓"␈α
" (blank).␈α We␈α
will␈αassume␈α
that␈α
␈↓αRPAR␈↓,␈α␈↓αLPAR␈↓,␈α
␈↓αPERIOD␈↓,␈αand␈α
␈↓αBLANK␈↓␈αdenote␈α
such␈α
atoms.␈α For
␈↓ ↓H␈↓example, if the next input character is "(" then
␈↓ ↓H␈↓␈↓ α@␈↓αeq[ratom[ ];LPAR]␈↓ is true (and the input pointer is moved to the next character!).
␈↓ ↓H␈↓␈↓αpatom[PERIOD]␈↓␈α
will␈α∞have␈α
the␈α
effect␈α∞of␈α
printing␈α∞a␈α
␈↓↓"."␈↓␈α
on␈α∞the␈α
output␈α
device.␈α∞ We␈α
will␈α∞discuss␈α
the
␈↓ ↓H␈↓structure of ␈↓αratom␈↓ and ␈↓αpatom␈↓ in a moment.
␈↓ ↓H␈↓␈↓αread␈↓␈α∞will␈α∞return␈α∞a␈α∂representation␈α∞of␈α∞a␈α∞legal␈α∂S-expr␈α∞or␈α∞list,␈α∞␈↓λα␈↓.␈α∞ The␈α∂call␈α∞on␈α∞␈↓αerr␈↓␈α∞will␈α∂terminate␈α∞the
␈↓ ↓H␈↓input scanning immediately.
␈↓ ↓H␈↓␈↓↓5.11␈↓ πrInput/Output: ␈↓αread␈↓↓ and ␈↓αprint␈↓↓ 253␈↓α
␈↓ ↓H␈↓␈↓αread_head␈↓␈αwill␈α
translate␈αstrings␈α
␈↓λα␈↓␈αacceptable␈α
in␈αthe␈α
context␈α"␈↓α(␈↓λα␈↓".␈α
Thus␈α␈↓λα␈↓␈α
being␈α␈↓α"A)"␈↓␈αor␈α
␈↓α"A (B . C))"␈↓
␈↓ ↓H␈↓would␈α⊃be␈α∩suitable␈α⊃for␈α∩␈↓αread_head␈↓;␈α⊃␈↓α(A)␈↓␈α∩and␈α⊃␈↓α(A (B . C))␈↓␈α∩are␈α⊃S-exprs␈α∩or␈α⊃lists.␈α∩ ␈↓α. A)␈↓␈α⊃would␈α∩not␈α⊃be
␈↓ ↓H␈↓acceptable since ␈↓α(. A)␈↓ is neither an S-expr nor list.
␈↓ ↓H␈↓αread <=λ[[ ]␈↓ αhλ[[j]␈↓ β([atom[j] →return[j];
␈↓ ↓H␈↓α␈↓ αh␈↓ β( is_lpar[j] → read_head[ ];
␈↓ ↓H␈↓α␈↓ αh␈↓ β( is_dot[j] → err[ ];
␈↓ ↓H␈↓α␈↓ αh␈↓ β( is_rpar[j] → err[ ]]
␈↓ ↓H␈↓α␈↓ αh[ratom[ ]]]
␈↓ ↓H␈↓␈↓αread_head␈↓ is looking for legal ␈↓λα␈↓'s in the context "␈↓α(␈↓λα␈↓". If it sees:
␈↓ ↓H␈↓␈↓ βHan atom, then ␈↓λα␈↓ is <atom>␈↓λβ␈↓α)␈↓;
␈↓ ↓H␈↓␈↓ βHa left parenthesis, then ␈↓λα␈↓ is ␈↓α(␈↓λβ␈↓α)␈↓λ∂␈↓α)␈↓;
␈↓ ↓H␈↓␈↓ βHa dot, then ␈↓λα␈↓ is ␈↓α.␈↓λβ␈↓α)␈↓;
␈↓ ↓H␈↓␈↓ βHa right parenthesis, then ␈↓λα␈↓ is ␈↓α)␈↓.
␈↓ ↓H␈↓αread_head <= λ[[ ]␈↓ βHλ[[j]␈↓ ∧λ[atom[j] → cons[j;read_tail[]];
␈↓ ↓H␈↓α␈↓ βH␈↓ ∧λ is_lpar[j] → cons[read_head[ ];read_tail[ ]];
␈↓ ↓H␈↓α␈↓ βH␈↓ ∧λ is_dot[j] → err[ ];
␈↓ ↓H␈↓α␈↓ βH␈↓ ∧λ is_rpar[j] → NIL]]
␈↓ ↓H␈↓α␈↓ βH[ratom[ ]]]
␈↓ ↓H␈↓␈↓αread_tail␈↓␈αis␈αlooking␈αfor␈αlegal␈α␈↓λα␈↓'s␈αin␈αthe␈αcontext␈α"␈↓α(␈↓<sexpr> ␈↓λα␈↓".␈α The␈αstructure␈αof␈αthis␈αfunction␈αis␈αthat
␈↓ ↓H␈↓of␈α␈↓αread_head␈↓␈αexcept␈αfor␈αrecognition␈αof␈αdots.␈α"␈↓α.␈↓λβ␈↓α)␈↓"␈α␈↓↓is␈↓␈αplausible␈αin␈αthe␈αcontext␈α"␈↓α(␈↓<sexpr> ␈↓λα␈↓".␈α It␈αis␈αup
␈↓ ↓H␈↓to ␈↓αread_cdr␈↓ to see if its expectations are fulfilled.
␈↓ ↓H␈↓αread_tail <= λ[[ ]␈↓ β8λ[[j]␈↓ βx[atom[j] → cons[j;read_tail[]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βx is_lpar[j] → cons[read_head[ ];read_tail[ ]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βx is_dot[j] → read_cdr[];
␈↓ ↓H␈↓α␈↓ β8␈↓ βx is_rpar[j] → NIL]]
␈↓ ↓H␈↓α␈↓ β8[ratom[ ]]]
␈↓ ↓H␈↓The only input legal after a dot is a S-expr or list followed by a right parenthesis.
␈↓ ↓H␈↓αread_cdr <= λ[[ ]␈↓ β8λ[[j]␈↓ βx[is_rpar[ratom[ ]] → j;
␈↓ ↓H␈↓α␈↓ β8␈↓ βx ␈↓
t␈↓α → err[ ] ]]
␈↓ ↓H␈↓α␈↓ β8[read[ ]]]
␈↓ ↓H␈↓Finally, here are some of the primitive recognizers which these functions use.
␈↓ ↓H␈↓α␈↓ β0is_dot[x] <= eq[x;PERIOD] is_lpar[x] <= eq[x;LPAR], ...␈↓ etc.
␈↓ ↓H␈↓Here are ␈↓αprint␈↓ and friends. ␈↓αterpri␈↓ initiates a new output line.
␈↓ ↓H␈↓␈↓↓254 static structure␈↓ *5.11␈↓
␈↓ ↓H␈↓α␈↓ ∧eprint <= λ[[x] prin0[x]; terpri[ ]; x].
␈↓ ↓H␈↓α␈↓The value of ␈↓αprint[x]␈↓ is ␈↓αx␈↓.
␈↓ ↓H␈↓αprin0 <= λ[[x]prog[[j]
␈↓ ↓H␈↓α␈↓ αX␈↓ βλ[atom[x] → return[patom[x]]];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλj ← x;
␈↓ ↓H␈↓α␈↓ αX␈↓ βλpatom[LPAR];
␈↓ ↓H␈↓α␈↓ αXa3␈↓ βλprin0[car[j]];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλ[null[cdr[j]] →␈↓ ∧Hpatom[RPAR];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλ␈↓ ∧Hreturn[x]];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλpatom[BLANK];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλ[atom[cdr[j]] →␈↓ ∧Hpatom[PERIOD];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλ␈↓ ∧Hpatom[BLANK];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλ␈↓ ∧Hpatom[cdr[j]];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλ␈↓ ∧Hpatom[RPAR];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλ␈↓ ∧Hreturn[x]];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλj ← cdr[j];
␈↓ ↓H␈↓α␈↓ αX␈↓ βλgo[a3] ]]
␈↓ ↓H␈↓Notice␈α∞that␈α∞we␈α∞have␈α∞used␈α∞the␈α∞extended␈α∞λ-expressions␈α∞and␈α∞conditional␈α∞expression␈α∞as␈α∞described␈α
in
␈↓ ↓H␈↓Section 4.3␈↓π 171␈↓.
␈↓ ↓H␈↓The␈α
basic␈α
␈↓αprint␈↓␈α∞routine␈α
allows␈α
us␈α∞to␈α
print␈α
data␈α∞structures␈α
and␈α
program␈α∞representations.␈α
However
␈↓ ↓H␈↓the␈α
printer␈α
will␈α
print␈α
duplications␈α
for␈α
a␈α
list␈α
structure␈α
which␈α
has␈α
shared␈α
branches␈α
and,␈α
worse␈αyet,␈α
will
␈↓ ↓H␈↓not␈αterminate␈αif␈α
it␈αis␈αgiven␈αa␈α
circular␈αstructure.␈αSome␈αimplementations␈α
of␈αLISP␈αremedy␈αthis␈α
ailment;
␈↓ ↓H␈↓see [Ter 75] or [Int 75].
␈↓ ↓H␈↓The␈αoutput␈αformat␈αis␈αa␈αsimple␈αlinear␈αstring␈αof␈αatoms,␈αnumbers,␈αspaces,␈αand␈αparens.␈αFor␈α
example␈αa
␈↓ ↓H␈↓␈↓αprint␈↓-based␈α
program␈αfor␈α
printing␈α
function␈αdefinitions␈α
might␈αprint␈α
the␈α
following␈αas␈α
the␈αdefinition␈α
of
␈↓ ↓H␈↓␈↓αmember␈↓:
␈↓ ↓H␈↓α␈↓ ∧λ(MEMBER␈α⊂(LAMBDA␈α⊂(X␈α⊂L)␈α⊂(COND␈α⊂((NULL
␈↓ ↓H␈↓α␈↓ ∧λL)␈α
NIL)␈α((EQ␈α
X␈α
(FIRST␈αL))␈α
T)␈α
(T␈α(MEMBER
␈↓ ↓H␈↓α␈↓ ∧λX (REST L))))))
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 171␈↓␈αNotice␈αtoo␈αthat␈α␈↓αprint[(A .(B . C))]␈↓␈αprints␈αas␈α␈↓α(A B . C)␈↓.␈αThis␈αis␈αbecause␈α␈↓αprint␈↓␈αdoesn't␈α
know␈αthat
␈↓ ↓H␈↓the␈α∞structure␈α∞is␈α∞not␈α∞a␈α∞list␈α∞until␈α∞it␈α∂sees␈α∞the␈α∞last␈α∞dotted-pair.␈α∞There␈α∞are␈α∞two␈α∞ways␈α∞of␈α∂handling␈α∞this:
␈↓ ↓H␈↓either␈α
require␈αa␈α
type-code,␈αtelling␈α
whether␈αthe␈α
structure␈αis␈α
a␈αdotted␈α
pair␈αor␈α
a␈αlist,␈α
represented␈α
as␈αa
␈↓ ↓H␈↓dotted␈α⊂pair.␈α⊂Then␈α⊂␈↓↓all␈↓␈α⊂dotted␈α∂pairs␈α⊂are␈α⊂printed␈α⊂in␈α⊂dot␈α⊂notation,␈α∂and␈α⊂␈↓↓all␈↓␈α⊂lists␈α⊂are␈α⊂printed␈α⊂in␈α∂list
␈↓ ↓H␈↓notation.␈α
The␈α
other␈α
alternative␈α
is␈α
to␈α
first␈α
examine␈α
the␈α
structure;␈α
if␈α
it␈α
is␈α
a␈α
list␈α∞representation,␈α
then
␈↓ ↓H␈↓print␈αit␈αthat␈αway,␈αotherwise␈αprint␈αit␈αas␈αa␈αdotted␈αpair.␈αThis␈αproblem␈αis␈αanother␈αindication␈αof␈α"object
␈↓ ↓H␈↓vs. representation".
␈↓ ↓H␈↓␈↓↓5.11␈↓ πrInput/Output: ␈↓αread␈↓↓ and ␈↓αprint␈↓↓ 255␈↓α
␈↓ ↓H␈↓The␈α
print␈α
routine␈αcan␈α
break␈α
the␈α
text␈αat␈α
the␈α
end␈αof␈α
any␈α
atom␈↓π 172␈↓;␈α
the␈αonly␈α
restriction␈α
we␈α
place␈αon
␈↓ ↓H␈↓printing of expressions is that what is ␈↓αprint␈↓-ed must be ␈↓αread␈↓-able.
␈↓ ↓H␈↓Even␈α
with␈αa␈α
small␈α
definition␈αlike␈α
this,␈α
we␈αhave␈α
difficulty␈α
deciphering␈αthe␈α
structure.␈αWhen␈α
functions
␈↓ ↓H␈↓or␈α≥lists␈α≤become␈α≥large␈α≤and␈α≥deeply␈α≤nested␈α≥the␈α≤readability␈α≥becomes␈α≥unmanageable.␈α≤Most
␈↓ ↓H␈↓implementations␈α∪of␈α∀LISP␈α∪supply␈α∀formatting␈α∪programs␈α∪called␈α∀"pretty-printers"␈α∪or␈α∀"grinders"␈α∪to
␈↓ ↓H␈↓supplement the basic print routine.
␈↓ ↓H␈↓A pretty-printer might print ␈↓αmember␈↓ as:
␈↓ ↓H␈↓α(MEMBER
␈↓ ↓H␈↓α (LAMBDA (X L)
␈↓ ↓H␈↓α (COND␈↓ αX((NULL L) NIL)
␈↓ ↓H␈↓α␈↓ αX((EQ X (FIRST L)) T)
␈↓ ↓H␈↓α␈↓ αX(T (MEMBER X (REST L))))))
␈↓ ↓H␈↓See Section 9.2 for a more detailed description of such functions.
␈↓ ↓H␈↓So␈α∩far␈α∩we␈α∪have␈α∩thrown␈α∩all␈α∪the␈α∩I/O␈α∩back␈α∩on␈α∪␈↓αratom␈↓␈α∩and␈α∩␈↓αpatom␈↓.␈α∪ Clearly␈α∩␈↓αratom␈↓␈α∩will␈α∪be␈α∩more
␈↓ ↓H␈↓interesting.␈αAll␈α␈↓αpatom␈↓␈α
need␈αdo␈αis␈αget␈α
the␈αp-name␈αand␈α
print␈αit.␈α ␈↓αratom␈↓␈αneeds␈α
to␈αdo␈αan␈αefficient␈α
search
␈↓ ↓H␈↓of␈αthe␈αatom␈αtable␈αand␈αif␈αthe␈αatom␈αis␈αnot␈αfound,␈αadd␈αit␈αto␈αthe␈αtable.␈α All␈α␈↓αratom␈↓␈αhas␈αto␈αwork␈αwith␈αis
␈↓ ↓H␈↓the␈αactual␈α
character␈αstring␈α
which␈αwill␈α
be␈αthe␈α
p-name␈αof␈α
some␈αatom.␈α
What␈α␈↓αratom␈↓␈α
could␈αdo␈α
is␈αlook␈α
at
␈↓ ↓H␈↓the␈αp-name␈αof␈αeach␈α
atom␈αcurrently␈αin␈αthe␈αtable␈α
of␈αatoms;␈αwhen␈αit␈αfinds␈α
a␈αmatch␈αit␈αreturns␈αa␈α
pointer
␈↓ ↓H␈↓to␈αthat␈αatom.␈αThis␈αis␈αessentially␈α
the␈αsearch␈αscheme␈αof␈α␈↓αassoc␈↓.␈α If␈α
the␈αappropriate␈αatom␈αis␈αnot␈αfound␈α
it
␈↓ ↓H␈↓can␈αbuild␈αa␈αnew␈αone␈αconsisting␈αof␈αthe␈αp-name,␈αadd␈αit␈αto␈αthe␈αtable,␈αand␈αreturn␈αa␈αpointer␈αto␈αthis␈αnew
␈↓ ↓H␈↓entry. In the next section we will introduce an alternative scheme called hashing.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓␈αYou␈αmight␈αhave␈αnoticed␈αthat␈αthe␈αdefinitions␈αof␈α␈↓αread_head␈↓␈αand␈α␈↓αread_tail␈↓␈αare␈αalmost␈αidentical:␈αthe
␈↓ ↓H␈↓difference␈α∞involves␈α∞treatment␈α∞of␈α∞dots.␈α∞ Write␈α
new␈α∞versions␈α∞of␈α∞these␈α∞functions␈α∞utilizing␈α∞a␈α
common
␈↓ ↓H␈↓routine and functional arguments.
␈↓ ↓H␈↓␈↓↓2.␈↓ Write a set of BNF equations that generate the same set of sentences that ␈↓αread␈↓ parses.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 172␈↓␈α⊂Some␈α⊂implementations␈α⊂even␈α⊂allow␈α⊂the␈α⊂printer␈α⊂to␈α⊂break␈α⊂in␈α⊂the␈α⊂middle␈α⊂of␈α⊂an␈α⊂atom.␈α⊂This␈α∂is
␈↓ ↓H␈↓accomplished␈αby␈αdesignating␈αa␈αspecial␈αcharacter␈αfor␈αcarriage␈αcontrol,␈αand␈αthe␈α␈↓αread␈↓␈αroutine␈αknows␈αto
␈↓ ↓H␈↓ignore the immediately following end-of-line sequence.
␈↓ ↓H␈↓␈↓↓256 static structure␈↓ (5.12␈↓
␈↓ ↓H␈↓␈↓ ∧␈␈↓↓5.12 Table Searching: Hashing␈↓
␈↓ ↓H␈↓Table␈α∞lookup␈α∞is␈α∞analogous␈α∞to␈α∞the␈α∞problem␈α∂of␈α∞looking␈α∞up␈α∞words␈α∞in␈α∞a␈α∞dictionary.␈α∞ The␈α∂scheme␈α∞of
␈↓ ↓H␈↓␈↓αassoc␈↓␈α∂is␈α∂analogous␈α∂to␈α∂a␈α∂person␈α∂beginning␈α∂at␈α∂page␈α∂one␈α∂of␈α∂the␈α∂dictionary␈α∂and␈α∂proceeding␈α∞linearly
␈↓ ↓H␈↓(page-by-page␈αand␈αword-by-word)␈αthrough␈αthe␈αbook␈αuntil␈αhe␈αfinds␈αthe␈αword␈αin␈αquestion.␈α What␈αwe
␈↓ ↓H␈↓normally␈αdo␈αis␈αlook␈αat␈αthe␈αfirst␈αcharacter␈αof␈αthe␈αword␈αand␈αgo␈αimmediately␈αto␈αthe␈αsubsection␈α
of␈αthe
␈↓ ↓H␈↓dictionary␈α
which␈α
has␈α
the␈α
words␈α
beginning␈α
with␈α
that␈α
character.␈α
We␈α
know␈α
that␈α
if␈α
we␈α
cannot␈αfind␈α
the
␈↓ ↓H␈↓definition␈αof␈αour␈αword␈αin␈αthat␈αsubsection␈α
we␈αneed␈αlook␈αno␈αfurther.␈α Usually␈αwe␈αdelimit␈α
our␈αsearch
␈↓ ↓H␈↓even␈α⊂further␈α∂by␈α⊂keying␈α∂on␈α⊂subsequent␈α∂characters␈α⊂in␈α∂the␈α⊂word.␈α∂ Finally␈α⊂we␈α∂may␈α⊂resort␈α⊂to␈α∂linear
␈↓ ↓H␈↓search␈α⊂to␈α⊂locate␈α⊂the␈α⊂word␈α⊃on␈α⊂a␈α⊂specific␈α⊂page␈α⊂or␈α⊂column.␈α⊃ Hashing␈α⊂is␈α⊂a␈α⊂similar␈α⊂scheme␈α⊃for␈α⊂the
␈↓ ↓H␈↓machine.␈α∂ We␈α∂might␈α⊂mimic␈α∂the␈α∂dictionary␈α∂search,␈α⊂subdividing␈α∂our␈α∂table␈α∂into␈α⊂26␈α∂subsections␈↓π 173␈↓.
␈↓ ↓H␈↓We␈αcan␈α
do␈αbetter.␈α
Since␈αit␈α
is␈αthe␈α
machine␈αwhich␈αwill␈α
subdivide␈αand␈α
index␈αinto␈α
the␈αtable,␈α
we␈αcan
␈↓ ↓H␈↓pick␈αa␈αscheme␈αwhich␈αis␈αcomputationally␈αconvenient␈αfor␈αthe␈αmachine.␈αBesides␈αbeing␈αconvenient,␈αthe
␈↓ ↓H␈↓scheme␈αshould␈αresult␈αin␈αrather␈αeven␈αdistribution␈αof␈αatoms␈αin␈αthe␈αsubsections.␈αIf␈αthe␈αmajority␈αof␈αthe
␈↓ ↓H␈↓atoms␈αend␈α
up␈αin␈α
the␈αsame␈α
partition␈αof␈α
the␈αtable␈α
we␈αwill␈α
have␈αgained␈α
little␈αtowards␈α
improving␈αthe
␈↓ ↓H␈↓search efficiency.
␈↓ ↓H␈↓An␈α
algorithm␈αused␈α
to␈αdetermine␈α
which␈αpartition␈α
a␈αparticular␈α
element␈αbelongs␈α
in␈αis␈α
called␈αa␈α
␈↓↓hashing
␈↓ ↓H␈↓↓algorithm␈↓␈α
or␈αhashing␈α
function.␈α One␈α
obstacle␈αfor␈α
such␈αschemes␈α
involves␈αthe␈α
management␈α
of␈αeach
␈↓ ↓H␈↓partition.␈αIf␈α
more␈αthan␈αone␈α
element␈α"hashes"␈αto␈α
a␈αpartition␈αthen␈α
we␈αhave␈αa␈α
␈↓↓collision␈↓.␈αThere␈αare␈α
two
␈↓ ↓H␈↓basic␈α⊂strategies␈α⊂available␈α⊂to␈α∂resolve␈α⊂such␈α⊂a␈α⊂collision.␈α∂The␈α⊂first,␈α⊂called␈α⊂␈↓↓open␈α⊂addressing␈↓␈α∂involves
␈↓ ↓H␈↓re-hashing␈α∞the␈α∞element,␈α∞thus␈α∞refining␈α∞the␈α∞partition,␈α∞until␈α∞no␈α∞collision␈α∞exists.␈α∞In␈α∞the␈α∞second,␈α∞called
␈↓ ↓H␈↓␈↓↓bucket␈α
hashing␈↓,␈α
the␈α
hashing␈α∞function␈α
hashes␈α
to␈α
a␈α
"bucket".␈α∞All␈α
the␈α
elements␈α
with␈α
the␈α∞same␈α
hash
␈↓ ↓H␈↓number␈αare␈αstored␈αin␈αthe␈αsame␈α"bucket";␈αa␈αsearch␈αis␈αused␈αto␈αdiscover␈αif␈αan␈αelement␈αis␈αin␈αthe␈αbucket.
␈↓ ↓H␈↓Since most LISP implementations use bucket hashing, we will describe that scheme in more detail.
␈↓ ↓H␈↓Each␈α∂LISP␈α∂atom␈α∞will␈α∂appear␈α∂in␈α∞at␈α∂most␈α∂one␈α∞bucket.␈α∂ All␈α∂␈↓αratom␈↓␈α∞has␈α∂to␈α∂work␈α∞with␈α∂is␈α∂␈↓αchr-str␈↓,␈α∞the
␈↓ ↓H␈↓encoding␈α
of␈α
the␈αactual␈α
name␈α
of␈α
the␈αatom.␈α
The␈α
hashing␈α
function␈αwill␈α
use␈α
␈↓αchr-str␈↓␈α
to␈αdetermine␈α
which
␈↓ ↓H␈↓bucket␈αto␈αexamine.␈α Given␈αthe␈αbucket␈αnumber,␈αwe␈αthen␈αrun␈αdown␈αthe␈αlist␈αof␈αatoms␈αin␈αthat␈αbucket,
␈↓ ↓H␈↓comparing␈αprint-names␈αagainst␈α␈↓αchr-str␈↓.␈α
If␈αthe␈αatom␈αwith␈αprint-name␈α
␈↓αchr-str␈↓␈αdoes␈αnot␈αappear␈αin␈α
that
␈↓ ↓H␈↓bucket␈αwe␈αare␈αassured␈αthat␈αit␈αdoes␈αnot␈αappear␈αanywhere␈αin␈αthe␈αtable.␈α In␈αthis␈αcase␈αwe␈αcreate␈αa␈αnew
␈↓ ↓H␈↓atom structure and add it to that bucket.
␈↓ ↓H␈↓Here is a sample hashing function:
␈↓ ↓H␈↓␈↓↓1.␈↓ Assume that we have N+1 buckets, numbered 0, 1, 2 ... N.
␈↓ ↓H␈↓␈↓↓2.␈↓ Take the numeric representation of ␈↓αchr-str␈↓ and divide that number by N+1.
␈↓ ↓H␈↓␈↓↓3.␈↓ Look at the remainder. It's a number between 0 and N.
␈↓ ↓H␈↓␈↓↓4.␈↓ Use that remainder as the index to the appropriate bucket.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 173␈↓ That is, a base 26 sort.
␈↓ ↓H␈↓␈↓↓5.12␈↓ λ≤Table Searching: Hashing 257␈↓
␈↓ ↓H␈↓The␈αLISP␈α
atom␈αtable,␈α
usually␈αcalled␈α
␈↓αOBLIST␈↓␈α(for␈α␈↓↓object␈α
list␈↓),␈αis␈α
a␈αlist␈α
of␈αbuckets.␈α
Each␈αbucket␈αis␈α
a
␈↓ ↓H␈↓list␈α∂of␈α∂the␈α∂atoms␈α∂which␈α∂`hash'␈α∂to␈α∂that␈α∂bucket.␈α∂ We␈α∂actually␈α∂represent␈α∂the␈α∂object␈α∂list␈α∂as␈α∂an␈α∞array
␈↓ ↓H␈↓named␈α⊂␈↓αoblist␈↓.␈α⊂ Arrays␈α⊂are␈α⊂discussed␈α⊂in␈α⊃full␈α⊂in␈α⊂Section 7.2,␈α⊂but␈α⊂basically␈α⊂are␈α⊂an␈α⊃efficient␈α⊂storage
␈↓ ↓H␈↓representation␈αfor␈αsequences␈αof␈αknown␈αlength.␈α
We␈αtypically␈αallocate␈αa␈αblock␈αof␈αsequential␈α
cells␈αand
␈↓ ↓H␈↓use␈α∂the␈α∂addressing␈α∂scheme␈α∂of␈α∂the␈α∂machine's␈α∂hardware␈α∂to␈α∂do␈α∂a␈α∂rapid␈α∂subscript␈α∂calculation.␈α∂ The
␈↓ ↓H␈↓hash␈αnumber␈αwill␈αgive␈αus␈αthe␈αarray␈αsubscript␈αand␈αwe␈αcan␈αgo␈αto␈αthe␈αright␈αbucket␈αimmediately.␈α We
␈↓ ↓H␈↓won't have to go ␈↓αcdr␈↓-ing down the object list to get to the bucket.
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
⊂ααααααα←ααααααα←αααα←βα# ~ #αβα⊃
␈↓"␈↓ ↓H␈↓
~ εαααβαααλ ↓
␈↓"␈↓ ↓H␈↓
~ ~ ~ ~←$
␈↓"␈↓ ↓H␈↓
~ ⊂ααα←ααα←ααα←βα# ~ #αβ→⊃
␈↓"␈↓ ↓H␈↓
↓ ↓ εαααβαααλ ↓
␈↓"␈↓ ↓H␈↓
... (to bucket 2) ... ...
␈↓"␈↓ ↓H␈↓
↓ ↓ εαααβαααλ ↓
␈↓"␈↓ ↓H␈↓
~ ... ⊂α←αβα# ~ ≤'~←$
␈↓"␈↓ ↓H␈↓
~ ↓ εαααβααα$
␈↓"␈↓ ↓H␈↓
~ %ααααααα→αααααα→αααααα⊃
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
(to bucket 1) (to bucket n)
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ~ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ ⊂αααπααα⊃ ⊂αααπαα⊃ %α→~ # ~ #αβ→ ...→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%→~ # ~ #αβ→...→~ # ~≤'~ %αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
%αβα∀ααα$ %αβα∀αα$ ↓ %→ ...
␈↓"␈↓ ↓H␈↓
~ ~ ⊂απααα⊃
␈↓"␈↓ ↓H␈↓
(to atom 1: (atom m: ~∃~ #αβ→(p-list of
␈↓"␈↓ ↓H␈↓
bucket 1) bucket 1) %α∀ααα$ atom 1: bucket n)
␈↓"␈↓ ↓H␈↓
~ ↓
␈↓"␈↓ ↓H␈↓
↓ ⊂απααα⊃ ⊂αααααααπααα⊃ ⊂αααπααα⊃ ⊂ααααααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
... ~∃~ #αβα→~ PNAME ~ #αβα→~ # ~ #αβ→~ SUBR ~ #αβ→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%α∀ααα$ %ααααααα∀ααα$ %αβα∀ααα$ %αααααα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
⊂αααπαα⊃ to primitive code
␈↓"␈↓ ↓H␈↓
~ # ~≤'~ for ␈↓αcar␈↓
␈↓"␈↓ ↓H␈↓
%αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
~CAR≡≡~
␈↓"␈↓ ↓H␈↓
%ααααα$
␈↓ ↓H␈↓↓␈↓ βzPartial Object List; where atom m:bucket 1 is ␈↓αCAR␈↓↓
␈↓ ↓H␈↓Note:␈α
The␈αtop␈α
level␈α
of␈α␈↓αOBLIST␈↓␈α
is␈α
stored␈αsequentially␈α
for␈α
fast␈αaccess␈α
by␈α
the␈αhasher;␈α
the␈α␈↓αcdr␈↓-parts␈α
are
␈↓ ↓H␈↓chained␈α
together␈α
in␈α
a␈α
(sequential)␈α
list␈αso␈α
that␈α
the␈α
structure␈α
of␈α
the␈αtable␈α
will␈α
be␈α
like␈α
any␈α
other␈αlist.
␈↓ ↓H␈↓The chained representation is used by any other LISP process␈↓π 174␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 174␈↓␈α∂In␈α∂particular,␈α∞the␈α∂garbage␈α∂collector␈α∂uses␈α∞this␈α∂linking.␈α∂As␈α∞a␈α∂further␈α∂implementation␈α∂note,␈α∞the
␈↓ ↓H␈↓implementors␈α∞of␈α∞MacLISP␈α∞noted␈α∞the␈α∞frequent␈α∞use␈α
of␈α∞single␈α∞character␈α∞atoms␈α∞and␈α∞added␈α∞a␈α
special
␈↓ ↓H␈↓section␈αto␈αthe␈αtop-level␈αof␈αthe␈α
object␈αlist.␈αA␈αcontiguous␈αblock␈αof␈α
cells,␈αof␈αsize␈αequal␈αto␈αthe␈αnumber␈α
of
␈↓ ↓H␈↓characters,␈αwas␈αadded.␈αOn␈αreading␈αa␈αsingle␈αcharacter␈αatom,␈αthe␈αcorresponding␈αentry␈αin␈αthe␈αtable␈αis
␈↓ ↓H␈↓examined.␈αA␈α␈↓αNIL␈↓␈αsays␈αthe␈αatom␈α
hasn't␈αbeen␈αseen␈αbefore;␈αotherwise␈αits␈αp-list␈α
representation␈αresides
␈↓ ↓H␈↓there.
␈↓ ↓H␈↓␈↓↓258 static structure␈↓ (5.12␈↓
␈↓ ↓H␈↓MacLISP␈α∞embellishes␈α
the␈α∞basic␈α
␈↓αOBLIST␈↓␈α∞idea␈α
in␈α∞an␈α
important␈α∞way.␈α
That␈α∞LISP␈α
system␈α∞will␈α
allow
␈↓ ↓H␈↓several␈αobject␈αlists␈αto␈αexist␈αsimultaneously␈αThis␈αis␈αuseful␈αsince␈αseveral␈αcooperating␈αLISP␈αsubsystems
␈↓ ↓H␈↓may␈α
exist;␈α
for␈α
example␈α
the␈α
LISP␈α
editor,␈α
debugger,␈αand␈α
compiler␈α
are␈α
all␈α
written␈α
in␈α
LISP␈α
and␈αmay␈α
all
␈↓ ↓H␈↓be␈α
used␈α
within␈α
the␈α
same␈α
interactive␈α
session.␈α
The␈α
difficulty␈α
is␈α
that␈α
each␈α
of␈α
those␈α
subsystems␈α
may␈α
use
␈↓ ↓H␈↓names␈α
which␈α
conflict␈α
with␈α
names␈α
in␈α
the␈α
user's␈α
programs.␈α
Multiple␈α
object␈α
lists␈α
are␈α
a␈α
way␈α
to␈α
overcome
␈↓ ↓H␈↓this␈α
problem.␈α
Only␈α
one␈α
object␈αlist␈α
is␈α
current␈α
at␈α
any␈α
time,␈αbut␈α
several␈α
may␈α
exist.␈α
There␈αare␈α
functions
␈↓ ↓H␈↓to create object lists, and object lists are swapped by λ-binding to the identifier ␈↓αobarray␈↓␈↓π 175␈↓.
␈↓ ↓H␈↓Consider:
␈↓ ↓H␈↓α␈↓ ¬`λ[[obarray]␈↓λx␈↓α][ob␈↓β1␈↓α].
␈↓ ↓H␈↓Assuming␈α∂that␈α∂␈↓αob␈↓β1␈↓␈α∂is␈α∂bound␈α∂to␈α∂an␈α∂object␈α⊂list,␈α∂then␈α∂within␈α∂the␈α∂evaluation␈α∂of␈α∂␈↓λx␈↓␈α∂the␈α⊂symbols␈α∂and
␈↓ ↓H␈↓bindings of ␈↓αob␈↓β1␈↓ would be accessible.
␈↓ ↓H␈↓Whether␈αa␈αlinear␈αsearch␈αand␈αstorage␈αtechnique,␈α
like␈α␈↓αassoc-pairlis␈↓,␈αor␈αa␈αmore␈αcomplex␈αtechnique␈α
like
␈↓ ↓H␈↓hashing␈α
should␈α
be␈α
employed␈α
depends␈α
on␈α
the␈α
application,␈α
and␈α
the␈α
speed␈α
and␈α
size␈α
of␈α
the␈α
machine.
␈↓ ↓H␈↓The␈αhash␈αtable␈αtakes␈αextra␈αspace␈αboth␈αfor␈αstorage␈αand␈αfor␈αprogram,␈αbut␈αgives␈αa␈αfaster␈αsearch␈αtime.
␈↓ ↓H␈↓The␈αlinear␈αtechnique␈α
requires␈αless␈αspace,␈α
but␈αcan␈αbe␈α
quite␈αslow.␈α Several␈α
books␈αcover␈αsearching␈α
and
␈↓ ↓H␈↓sorting in great detail ([Gri 71], [Knu 72]).
␈↓ ↓H␈↓Finally,␈αwe␈αwant␈αto␈αpresent␈αa␈αversion␈αof␈α␈↓αratom␈↓␈αwhich␈αuses␈αa␈αhash␈αorganization.␈α In␈αthis␈αdiscussion,
␈↓ ↓H␈↓we␈α
will␈α
restrict␈α
ourselves␈α
to␈α
recognition␈α
of␈αatoms,␈α
leaving␈α
the␈α
reader␈α
to␈α
supply␈α
the␈α
necessary␈αparts
␈↓ ↓H␈↓for recognition of numbers. We will recognize three classes of characters:
␈↓ ↓H␈↓␈↓↓1.␈↓ The class of letters will include the alphabetic characters.
␈↓ ↓H␈↓␈↓↓2.␈↓␈α∞The␈α∞class␈α∞of␈α∞delimiters␈α∞consists␈α∞of␈α∞those␈α∞characters␈α∞which␈α∞signal␈α∞the␈α∞end␈α∞of␈α∞an␈α∞atom.␈α∞For␈α∞this
␈↓ ↓H␈↓␈↓ ↓xscanner we assume space and carriage control are delimiters.
␈↓ ↓H␈↓␈↓↓3.␈↓ The special characters will consist of "(", ")" and "." .
␈↓ ↓H␈↓Special␈αcharacters␈αalso␈αact␈αas␈αdelimiters␈αin␈αLISP␈αand␈αthis␈αresults␈αin␈αa␈αslight␈αcomplication.␈αConsider
␈↓ ↓H␈↓the␈αpartial␈αstring␈α"␈↓αAB )C␈↓".␈αOur␈αscanner␈αshould␈αscan␈αthe␈α"␈↓αA␈↓",␈αscan␈αthe␈α"␈↓αB␈↓",␈αand␈αscanning␈αthe␈αspace,
␈↓ ↓H␈↓should␈α
recognize␈α
a␈α∞delimiter.␈α
It␈α
should␈α
recognize␈α∞the␈α
␈↓αAB␈↓␈α
as␈α
an␈α∞atom,␈α
and␈α
signal␈α
␈↓αread␈↓.␈α∞The␈α
string
␈↓ ↓H␈↓will␈α
be␈α
reduced␈α
to␈α
"␈↓α)C␈↓".␈α
The␈α
next␈α
time␈α␈↓αread␈↓␈α
calls␈α
␈↓αratom␈↓␈α
the␈α
right␈α
parenthesis␈α
will␈α
be␈αseen,␈α
recognized
␈↓ ↓H␈↓as a special character and an indication of that will be returned to ␈↓αread␈↓.
␈↓ ↓H␈↓Now␈αconsider␈αthe␈αstring␈α"␈↓αAB)C␈↓";␈α␈↓αratom␈↓␈αwill␈αscan␈α"␈↓αA␈↓"␈αand␈α"␈↓αB␈↓"␈αas␈αbefore.␈αIt␈αwill␈αthen␈αscan␈αthe␈α")".␈αIt
␈↓ ↓H␈↓now␈α⊂needs␈α⊂to␈α⊂do␈α⊂␈↓↓two␈↓␈α⊂things;␈α⊂it␈α⊂must␈α⊂signal␈α⊂␈↓αread␈↓␈α⊂about␈α⊂the␈α⊂atom␈α⊂it␈α⊂has␈α⊂seen,␈α⊂but␈α⊂it␈α⊃must␈α⊂also
␈↓ ↓H␈↓remember␈α
the␈α
")"␈α
so␈α
that␈α
the␈α
␈↓↓next␈↓␈α
time␈α
␈↓αread␈↓␈αasks␈α
for␈α
information,␈α
it␈α
sees␈α
the␈α
")"␈α
and␈α
not␈α
the␈α"␈↓αC␈↓".
␈↓ ↓H␈↓We␈αhandle␈α
this␈αproblem␈αby␈α
using␈αa␈αglobal␈α
variable␈αnamed␈α␈↓αlst_chr␈↓.␈α
This␈αvariable␈αis␈α
initialized␈αto
␈↓ ↓H␈↓␈↓αNIL␈↓␈αand␈αremains␈αthat␈αway␈αuntil␈αour␈αanomalous␈αsituation␈αoccurs.␈αAt␈αthat␈αtime␈αthe␈αspecial␈αcharacter
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 175␈↓␈αAn␈αobject␈αlist␈αis␈αcalled␈αobject␈αarray␈αin␈αMacLISP␈αsince␈αthe␈αtable␈αis␈αrepresented␈αas␈αan␈αarray.␈αWe
␈↓ ↓H␈↓discuss arrays in Section 7.2.
␈↓ ↓H␈↓␈↓↓5.12␈↓ λ≤Table Searching: Hashing 259␈↓
␈↓ ↓H␈↓is␈αplaced␈αin␈α
␈↓αlst_chr␈↓,␈αand␈α␈↓αratom␈↓␈α
exits␈αnormally.␈αSo,␈α
whenever␈α␈↓αratom␈↓␈αis␈α
called,␈αthe␈αfirst␈α
thing␈αit␈αdoes␈α
is
␈↓ ↓H␈↓check␈α∞the␈α∞contents␈α∂of␈α∞␈↓αlst_chr␈↓.␈α∞ If␈α∂it␈α∞is␈α∞non-empty,␈α∞its␈α∂contents␈α∞is␈α∞returned,␈α∂as␈α∞␈↓αlst_chr␈↓␈α∞is␈α∂set␈α∞empty
␈↓ ↓H␈↓again.
␈↓ ↓H␈↓αratom <=λ[[] prog[[chr]
␈↓ ↓H␈↓α␈↓ β8␈↓ βX[lst_chr → swap[lst_chr;chr];return[chr]];
␈↓ ↓H␈↓α␈↓ β8a␈↓ βXchr ← readch[];
␈↓ ↓H␈↓α␈↓ β8␈↓ βX[is_let[chr] → stuf_buf[chr];return[ratom␈↓β1␈↓α[]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βX is_delim[chr] → go[a];
␈↓ ↓H␈↓α␈↓ β8␈↓ βX is_spec[chr] → return[chr]]]]
␈↓ ↓H␈↓This␈αprocedure␈αuses␈αtricks␈αadvertised␈αin␈αSection 5.5,␈αusing␈α␈↓αlst_chr␈↓␈αas␈αa␈αpredicate,␈αand␈αknowing␈αthat
␈↓ ↓H␈↓␈↓αprog␈↓␈α∀variables␈α∀are␈α∀initialized␈α∀to␈α∀␈↓αNIL␈↓␈α∀and␈α∪that␈α∀the␈α∀representation␈α∀of␈α∀␈↓
f␈↓␈α∀is␈α∀␈↓αNIL␈↓.␈α∀ With␈α∪that
␈↓ ↓H␈↓knowledge, ␈↓αswap␈↓ swaps the contents of ␈↓αchr␈↓ and ␈↓αlst_chr␈↓.
␈↓ ↓H␈↓The␈αroutine␈α␈↓αreadch␈↓␈αgets␈αthe␈αnext␈αcharacter,␈αand␈α␈↓αstuf_buf␈↓␈αis␈αused␈αto␈αsave␈αthe␈αcharacter␈αstring␈αwhich
␈↓ ↓H␈↓is to become an atom. The character string is built up in ␈↓αbuf␈↓.
␈↓ ↓H␈↓αratom␈↓β1␈↓α <= λ[[] prog[[chr]
␈↓ ↓H␈↓α␈↓ β8l␈↓ βXchr ← readch[];
␈↓ ↓H␈↓α␈↓ β8␈↓ βX[is_delim[chr] → return[intern[buf]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βX is_spec[chr] → lst_chr ← chr; return[intern[buf]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βX ␈↓
t␈↓α → stufbuf[chr]; go[l]]]]
␈↓ ↓H␈↓If ␈↓αratom␈↓β1␈↓ sees a special character it is saved in ␈↓αlst_chr␈↓.
␈↓ ↓H␈↓αintern <= λ[[l] prog[[chr-str]
␈↓ ↓H␈↓α␈↓ β8␈↓ βXchr-str ← maknam[buf];
␈↓ ↓H␈↓α␈↓ β8␈↓ βXbucket ← oblist[hash[chr-st]];
␈↓ ↓H␈↓α␈↓ β8a␈↓ βX[null[bucket] → return[insert[chr-str]]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βX[right-one[get[first[bucket];PNAME];chr_str] → return[first[bucket]]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βXbucket ← rest[bucket];
␈↓ ↓H␈↓α␈↓ β8␈↓ βXgo[a]]]
␈↓ ↓H␈↓␈↓αmaknam␈↓␈α⊂takes␈α⊂our␈α⊂character␈α⊂string␈α⊂and␈α⊂converts␈α⊂it␈α⊂into␈α⊂an␈α⊂appropriate␈α⊂numeric␈α⊂representation.
␈↓ ↓H␈↓␈↓αhash␈↓␈α
returns␈α
the␈α
bucket␈α
number␈α∞of␈α
its␈α
argument,␈α
and␈α
␈↓αinsert␈↓␈α
builds␈α∞the␈α
atom␈α
and␈α
inserts␈α
it␈α∞into␈α
a
␈↓ ↓H␈↓bucket. ␈↓αright-one␈↓ is a predicate used to check if an atom has the right print-name.
␈↓ ↓H␈↓An␈α∪implementation␈α∪of␈α∪␈↓αratom␈↓␈α∪may␈α∪be␈α∀generalized␈α∪so␈α∪that␈α∪the␈α∪class␈α∪of␈α∪special␈α∀characters␈α∪and
␈↓ ↓H␈↓delimiters␈α∂can␈α⊂be␈α∂varied.␈α⊂This␈α∂is␈α∂done␈α⊂using␈α∂a␈α⊂representation␈α∂of␈α∂a␈α⊂character␈α∂table␈α⊂whose␈α∂name
␈↓ ↓H␈↓entries␈α
are␈α
characters,␈α
and␈α
whose␈α
value␈αentries␈α
determine␈α
the␈α
␈↓αratom␈↓␈α
properties.␈α
This␈α
allows␈αLISP
␈↓ ↓H␈↓␈↓↓260 static structure␈↓ (5.12␈↓
␈↓ ↓H␈↓users␈α
to␈αdefine␈α
their␈αown␈α
parsers␈αand␈α
scanners.␈α LISP's␈α
modifiable␈αinput␈α
routine,␈αcoupled␈α
with␈αits
␈↓ ↓H␈↓data␈α↔structures␈α↔and␈α↔extendible␈α↔evaluator␈α_make␈α↔LISP␈α↔an␈α↔excellent␈α↔tool␈α↔for␈α_building␈α↔more
␈↓ ↓H␈↓sophisticated language systems.
␈↓ ↓H␈↓On␈αpage 195␈αwe␈αintroduced␈αthe␈αabbreviation␈α␈↓λ`␈↓αx␈↓␈αfor␈α␈↓αquote[x]␈↓.␈α This␈α␈↓αquote␈↓␈αfacility␈αis␈αan␈αinstance␈αof␈αa
␈↓ ↓H␈↓device␈αcalled␈αa␈α␈↓αread␈↓ macro.␈α
Such␈αan␈αabbreviational␈αfacility␈αis␈α
present␈αin␈αseveral␈αversions␈α
of␈αLISP
␈↓ ↓H␈↓and␈αit␈αis␈αthe␈αduty␈αof␈α␈↓αratom␈↓␈αto␈αrecognize␈αsuch␈αconstructs.␈α Whenever␈α␈↓αratom␈↓␈αsees␈αthe␈αprefix␈α␈↓λ`␈↓␈αit␈αreads
␈↓ ↓H␈↓the␈αnext␈αS-expr␈α␈↓λα␈↓␈α
and␈αreturns␈αthe␈αlist␈α
␈↓α(QUOTE␈α␈↓λα␈↓α)␈↓␈αas␈αvalue.␈α
In␈αsome␈αsystems␈α([Moo 74])␈α
the␈αusers
␈↓ ↓H␈↓may define their own ␈↓αread␈↓ macros. For example a definition like:
␈↓ ↓H␈↓α␈↓ ¬⊃' <␈↓βr␈↓α= λ[[] list[QUOTE;read[]]]
␈↓ ↓H␈↓would␈α
signal␈α
LISP␈α
to␈α
change␈αthe␈α
character␈α
table␈α
entry␈α
for␈α
" ' "␈αto␈α
be␈α
a␈α
␈↓αread␈↓ macro.␈α
If␈α" ' "␈α
appeared
␈↓ ↓H␈↓during␈α
an␈α∞input␈α
operation,␈α∞then␈α
the␈α∞body␈α
of␈α∞the␈α
␈↓αread␈↓-macro␈α∞would␈α
be␈α∞evaluated;␈α
that␈α∞would␈α
call
␈↓ ↓H␈↓␈↓αread␈↓,␈α∞and␈α∂then␈α∞form␈α∂a␈α∞list␈α∂with␈α∞␈↓αQUOTE␈↓␈α∂and␈α∞the␈α∂result.␈α∞The␈α∂resulting␈α∞list␈α∂would␈α∞be␈α∂returned␈α∞to
␈↓ ↓H␈↓within the original input process.
␈↓ ↓H␈↓MacLISP␈α⊂also␈α⊂defines␈α⊂a␈α⊂comment␈α⊂facility␈α⊃using␈α⊂a␈α⊂␈↓αread␈↓ macro.␈α⊂ The␈α⊂occurrence␈α⊂of␈α⊃a␈α⊂semi-colon
␈↓ ↓H␈↓signals the beginning of a comment; all characters to the end of the line are taken as commentary.
␈↓ ↓H␈↓Several␈αimplementations␈αalso␈αinclude␈αabbreviations␈αto␈αdecrease␈αthe␈αnumber␈αof␈αparentheses␈αneeded.
␈↓ ↓H␈↓For␈αexample␈α"["␈αand␈α"]"␈αare␈αoften␈αdefined␈αto␈αbe␈α"super-parentheses".␈α The␈α"["␈αacts␈αlike␈αa␈α"("␈αbut␈αits
␈↓ ↓H␈↓scope␈α∀runs␈α∀to␈α∀the␈α∀next␈α∀"]",␈α∪constructing␈α∀sufficient␈α∀")"␈α∀to␈α∀balance␈α∀the␈α∀intervening␈α∪expression.
␈↓ ↓H␈↓Similarly,␈α∂the␈α∂scope␈α∂of␈α∂a␈α∂"]"␈α∂extends␈α∂to␈α⊂the␈α∂prior␈α∂matching␈α∂"[";␈α∂if␈α∂none␈α∂exists,␈α∂the␈α⊂expression␈α∂is
␈↓ ↓H␈↓completed by supplying sufficient ")" to balance.
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓α␈↓ αV((A B) ((C D E))) = ((A B) ((C D E))] = [(A B) ((C D E))] = ((A B) ((C D E]
␈↓ ↓H␈↓α␈↓ ¬2(A [B (C]) = (A (B (C)))
␈↓ ↓H␈↓Regardless␈αof␈αthe␈αspecifics␈αof␈αthe␈αimplementation,␈αthe␈αinput␈αroutines␈αwill␈αread␈αa␈αlist␈αrepresentation
␈↓ ↓H␈↓of␈α
a␈αLISP␈α
expression␈αand␈α
convert␈αit␈α
into␈αan␈α
S-expr.␈α
For␈αexample,␈α
let's␈αsee␈α
what␈αhappens␈α
if␈αwe␈α
want
␈↓ ↓H␈↓to evaluate
␈↓ ↓H␈↓α␈↓ ε eq[x;A].
␈↓ ↓H␈↓This will be presented to the machine as:
␈↓ ↓H␈↓α␈↓ ¬N(EQ X (QUOTE A))
␈↓ ↓H␈↓␈↓↓5.12␈↓ λ≤Table Searching: Hashing 261␈↓
␈↓ ↓H␈↓␈↓αread␈↓␈αwill␈αbegin␈αparsing␈αthe␈αsequence␈αof␈αcharacters;␈αit␈αwill␈αdepend␈αon␈α␈↓αratom␈↓␈αto␈αreturn␈αindications␈αof
␈↓ ↓H␈↓the␈αspecial␈αcharacters,␈αand␈αwill␈αdepend␈αon␈α␈↓αratom␈↓␈αto␈αproperly␈αrepresent␈αeach␈αoccurrence␈αof␈αan␈αatom.
␈↓ ↓H␈↓The␈αparser␈αknows␈αabout␈αthe␈αrepresentation␈αwe␈αhave␈αchosen␈αfor␈αlists␈αand␈αwill␈αuse␈α␈↓αcons␈↓␈αto␈αbuild␈αup
␈↓ ↓H␈↓the S-expression form:
␈↓"␈↓ ↓H␈↓
⊂ααααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ EQ ~ #αβα→~ X ~ #αβα→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αααα∀ααα$ %ααα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
~ ⊂αααααααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%→~ QUOTE ~ #αβα→~ A ~≤'~
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓The␈αreferences␈α
to␈αthe␈αatoms␈α
␈↓αEQ,␈αX,␈α
A,␈↓␈αand␈α␈↓αQUOTE␈↓␈α
are␈αactually␈α
pointers␈αto␈αthe␈α
atoms.␈αEach␈αatom␈α
is
␈↓ ↓H␈↓located only once by the reader. After that we have direct access to atom and its property list.
␈↓ ↓H␈↓Since the input routines perform several ␈↓αcons␈↓ operations; we should look at the details of ␈↓αcons␈↓.
␈↓ ↓H␈↓␈↓ ¬$␈↓↓5.13 A First Look At ␈↓αcons␈↓␈↓α
␈↓ ↓H␈↓The␈α∞effect␈α∞of␈α∞the␈α∞␈↓αcons␈↓␈α∞operation␈α∞is␈α∞quite␈α
different␈α∞from␈α∞that␈α∞of␈α∞the␈α∞other␈α∞LISP␈α∞primitives.␈α
The
␈↓ ↓H␈↓other␈αprimitives␈αmanipulate␈αexisting␈αS-expressions,␈αwhereas␈α␈↓αcons␈↓␈αmust␈αconstruct␈αa␈αnew␈α
S-expression
␈↓ ↓H␈↓from␈αtwo␈αexisting␈αS-exprs.␈α Given␈αrepresentations␈αof␈αtwo␈αS-exprs,␈αsay␈α␈↓αx␈↓␈αand␈α␈↓αy,␈αcons[x;y]␈↓␈αmust␈αget␈αa
␈↓ ↓H␈↓new␈α
cell,␈α∞put␈α
a␈α∞pointer␈α
to␈α
the␈α∞representation␈α
of␈α∞␈↓αx␈↓␈α
in␈α
the␈α∞␈↓αcar␈↓-part␈α
of␈α∞the␈α
cell␈α
and␈α∞a␈α
pointer␈α∞to␈α
the
␈↓ ↓H␈↓representation of ␈↓αy␈↓ in the ␈↓αcdr␈↓-part and return a pointer to the new cell:
␈↓"␈↓ ↓H␈↓
␈↓result of ␈↓αcons[x;y]␈↓
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
~ ⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
%ααααααααα→~ # ~ # ~
␈↓"␈↓ ↓H␈↓
%ααβαα∀ααβαα$
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
⊂αααα$ %αααα⊃
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
␈↓rep. of ␈↓αx ␈↓rep. of ␈↓αy␈↓
␈↓ ↓H␈↓When␈αa␈αcomputation␈αis␈αbegun,␈αonly␈αthe␈αatom␈αstructure␈αfor␈αthe␈αinitial␈αLISP␈αsymbol␈αtable␈αuses␈αcells
␈↓ ↓H␈↓in␈αthe␈αpointer area.␈α
The␈αremaining␈αpointer cells␈α
are␈αlinked␈αtogether␈α
and␈αform␈αthe␈α
␈↓↓free␈αspace␈αlist␈↓␈α
or
␈↓ ↓H␈↓FS␈αlist␈↓π 176␈↓.␈α Whenever␈α␈↓αcons␈↓␈αneeds␈αa␈αcell,␈αthe␈αfirst␈αcell␈αin␈αthe␈αFS␈αlist␈αis␈αused␈αand␈αthe␈αFS␈αlist␈αis␈αset␈αto
␈↓ ↓H␈↓the ␈↓αrest␈↓ of the FS list.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 176␈↓␈αThe␈αLISP␈αfree␈αspace␈αlist␈αis␈αan␈αinstance␈αof␈α"heap storage" ([Alg 75]).␈αThe␈αidea␈αof␈αheap␈αstorage
␈↓ ↓H␈↓is␈α∀that␈α∀storage␈α∀allocation␈α∪is␈α∀not␈α∀well␈α∀disciplined␈α∀enough␈α∪that␈α∀is␈α∀is␈α∀controllable␈α∀implicitly␈α∪by
␈↓ ↓H␈↓procedure entry and exit. Therefore some more global management scheme is implied.
␈↓ ↓H␈↓␈↓↓262 static structure␈↓ (5.13␈↓
␈↓ ↓H␈↓For example the following represents the effect of ␈↓αcons[A;B]␈↓:
␈↓"␈↓ ↓H␈↓
␈↓αenv␈↓
␈↓αdest␈↓
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
⊂ααπαα⊃ ⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
~ ~ #α→... ~ #αβα⊃
␈↓"␈↓ ↓H␈↓
εααβααλ εααπααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ #β→⊃ ... ↓
␈↓"␈↓ ↓H␈↓
εααβααλ ↓ ~ ~ ~←$
␈↓"␈↓ ↓H␈↓
~ ~ #βαααα⊃ εααβααλ Pt␈↓βFS␈↓
␈↓"␈↓ ↓H␈↓
%αα∀αα$ ↓ ↓ ... ↓
␈↓"␈↓ ↓H␈↓
~ ~ %αα∀αα$ ~
␈↓"␈↓ ↓H␈↓
~ %→ααα→αα→⊃ ~
␈↓"␈↓ ↓H␈↓
↓ ↓ ↓
␈↓"␈↓ ↓H␈↓
⊂απααα⊃ ⊂απααα⊃ ⊂ααπααα⊃ ⊂ααπααα⊃ ⊂ααπαα⊃
␈↓"␈↓ ↓H␈↓
~∃~ #αβ→... ~∃~ #αβ→ ... ~≤'~ #αβ→~≤'~ #αβ→ ...→~≤'~≤'~
␈↓"␈↓ ↓H␈↓
%α∀ααα$ %α∀ααα$ %αα∀ααα$ %αα∀ααα$ %αα∀αα$
␈↓"␈↓ ↓H␈↓
atom A atom B
␈↓"␈↓ ↓H␈↓
␈↓ ε%␈↓↓Before␈↓
␈↓"␈↓ ↓H␈↓
␈↓αenv␈↓
␈↓αdest␈↓
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
⊂ααπαα⊃ ⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
~ ~ #α→... ~ #αβα⊃
␈↓"␈↓ ↓H␈↓
εααβααλ εααπααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ #β→⊃ ... ←$
␈↓"␈↓ ↓H␈↓
εααβααλ ↓ ~ ~ #ααα→ααααα→αααα→⊃
␈↓"␈↓ ↓H␈↓
~ ~ #βαααα⊃ εααβααλ ↓ Pt␈↓βFS␈↓
␈↓"␈↓ ↓H␈↓
%αα∀αα$ ↓ ↓ ... ~ ↓
␈↓"␈↓ ↓H␈↓
~ ~ %αα∀αα$ ~ %ααα→⊃
␈↓"␈↓ ↓H␈↓
~ %→ααα→αα→⊃ ~ ~
␈↓"␈↓ ↓H␈↓
↓ ↓ ↓ ↓
␈↓"␈↓ ↓H␈↓
⊂απααα⊃ ⊂απααα⊃ ⊂αααπααα⊃ ⊂ααπααα⊃ ⊂ααπαα⊃
␈↓"␈↓ ↓H␈↓
~∃~ #αβ→... ~∃~ #αβ→ ... ~ # ~ # ~ ~≤'~ #αβ→ ...→~≤'~≤'~
␈↓"␈↓ ↓H␈↓
%α∀ααα$ %α∀ααα$ %αβα∀αβα$ %αα∀ααα$ %αα∀αα$
␈↓"␈↓ ↓H␈↓
↑ ↑ ↓ ↓
␈↓"␈↓ ↓H␈↓
%ααααα←ααααα←ααααα←ααααα←αααααα$ ~
␈↓"␈↓ ↓H␈↓
↑ ↓
␈↓"␈↓ ↓H␈↓
%←ααααα←ααααα←αααααα$
␈↓"␈↓ ↓H␈↓
␈↓ ε,␈↓↓After␈↓
␈↓ ↓H␈↓As␈αthe␈αcomputation␈αcontinues,␈αcells␈αare␈αtaken␈αfrom␈αthe␈αFS␈αlist.␈α When␈αa␈α␈↓αcons␈↓␈αoperation␈αneeds␈αa␈αcell
␈↓ ↓H␈↓and␈α∂the␈α∂FS␈α∂list␈α∂is␈α⊂empty,␈α∂the␈α∂computation␈α∂is␈α∂suspended␈α⊂and␈α∂a␈α∂␈↓↓storage␈α∂reclaimer␈↓␈α∂is␈α⊂called.␈α∂The
␈↓ ↓H␈↓reclaimer␈α∞is␈α∂often␈α∞known␈α∞by␈α∂a␈α∞more␈α∞colorful␈α∂name: ␈α∞␈↓↓garbage␈α∞collector␈↓.␈α∂ The␈α∞job␈α∞of␈α∂the␈α∞garbage
␈↓ ↓H␈↓collector is to locate cells for a new FS list.
␈↓ ↓H␈↓␈↓↓5.14␈↓ εLStorage Management: Garbage Collection 263␈↓
␈↓ ↓H␈↓␈↓ ∧⊗␈↓↓5.14 Storage Management: Garbage Collection␈↓
␈↓ ↓H␈↓During␈α⊂the␈α∂course␈α⊂of␈α⊂a␈α∂computation,␈α⊂contents␈α⊂of␈α∂cells␈α⊂which␈α∂were␈α⊂taken␈α⊂from␈α∂the␈α⊂FS␈α⊂list␈α∂often
␈↓ ↓H␈↓become unnecessary. For example, if we ask LISP to evaluate something as simple as:
␈↓ ↓H␈↓␈↓ βn␈↓α(CONS (QUOTE A) (QUOTE B)),␈↓ many cells are used:
␈↓ ↓H␈↓␈↓↓1.␈↓ At least seven cells are needed just to read in the expression:
␈↓"␈↓ ↓H␈↓
⊂ααααααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ CONS ~ #αβα→~ # ~ #αβα→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αααααα∀ααα$ %αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ↓ ⊂αααααααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ %→~ QUOTE ~ #αβα→~ B ~≤'~
␈↓"␈↓ ↓H␈↓
~ %ααααααα∀ααα$ %ααα∀αα$
␈↓"␈↓ ↓H␈↓
~ ⊂αααααααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%α→~ QUOTE ~ #αβα→~ A ~≤'~
␈↓"␈↓ ↓H␈↓
%ααααααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓If some of the atoms are not present in the atom table, more cells will be needed.
␈↓ ↓H␈↓␈↓↓2.␈↓ One cell will be needed to perform the ␈↓αcons␈↓ operation. See the previous example.
␈↓ ↓H␈↓After␈α
the␈α
computation␈α
is␈α
completed,␈α
LISP␈α
will␈α∞print␈α
"␈↓α(A . B)␈↓"␈α
and␈α
wait␈α
for␈α
more␈α
input.␈α∞After␈α
the
␈↓ ↓H␈↓␈↓αprint␈↓␈α⊂statement␈α⊂is␈α⊂completed␈α⊂none␈α⊂of␈α⊂the␈α∂eight␈α⊂mentioned␈α⊂cells␈α⊂are␈α⊂needed.␈α⊂ They␈α⊂are␈α∂garbage.
␈↓ ↓H␈↓Why␈α
not␈α∞simply␈α
return␈α∞these␈α
`garbage␈α
cells'␈α∞explicitly␈α
to␈α∞the␈α
FS␈α
list?␈α∞ That␈α
could␈α∞be␈α
done␈α∞in␈α
this
␈↓ ↓H␈↓case,␈αbut␈αfrequently␈αit␈αis␈αdifficult␈αto␈αknow␈αexactly␈αwhich␈αcells␈α␈↓¬are␈↓␈αgarbage.␈α Experiments␈αhave␈αbeen
␈↓ ↓H␈↓performed␈αin␈αwhich␈αLISP␈αprogrammers␈αwere␈αallowed␈αto␈αreturn␈α`garbage'␈αto␈αthe␈αFS␈αlist␈αthemselves.
␈↓ ↓H␈↓The␈α
results␈α
were␈α
disastrous;␈α
list␈α
structure␈α
thought␈α∞to␈α
be␈α
garbage␈α
was␈α
returned␈α
to␈α
the␈α
FS␈α∞list␈α
even
␈↓ ↓H␈↓though␈α∂the␈α∂structure␈α∞was␈α∂still␈α∂being␈α∞used␈α∂by␈α∂other␈α∞computations.␈α∂In␈α∂Section 7.6␈α∞we␈α∂will␈α∂see␈α∞how
␈↓ ↓H␈↓these difficulties can arise.
␈↓ ↓H␈↓The␈α∂responsibility␈α⊂for␈α∂reclamation␈α∂is␈α⊂therefore␈α∂passed␈α⊂to␈α∂the␈α∂LISP␈α⊂system.␈α∂ The␈α⊂␈↓αcons␈↓␈α∂procedure
␈↓ ↓H␈↓removes␈α
cells␈α∞from␈α
the␈α∞FS␈α
list,␈α∞and␈α
its␈α
FWS␈α∞counterpart␈α
␈↓αfwcons␈↓,␈α∞removes␈α
cells␈α∞from␈α
the␈α∞FWS␈α
list
␈↓ ↓H␈↓when␈α⊂making␈α⊂numbers␈α⊂or␈α⊂print-names.␈α⊂ These␈α⊃two␈α⊂functions␈α⊂are␈α⊂the␈α⊂only␈α⊂functions␈α⊃allowed␈α⊂to
␈↓ ↓H␈↓manipulate the free storage lists. When either list becomes empty, the garbage collector is called.
␈↓ ↓H␈↓␈↓↓␈↓ βbThe fundamental assumption of garbage collection is:␈↓
␈↓ ↓H␈↓␈↓ αhAt␈α
any␈α
point␈α
in␈α
a␈α
LISP␈α∞computation,␈α
all␈α
cells␈α
which␈α
contain␈α
parts␈α∞of␈α
the
␈↓ ↓H␈↓␈↓ αhcomputation␈α∪are␈α∪reachable␈α∪(by␈α∀␈↓αcar-cdr␈↓␈α∪chains)␈α∪through␈α∪a␈α∪fixed␈α∀set␈α∪of
␈↓ ↓H␈↓␈↓ αhknown cells or base registers.
␈↓ ↓H␈↓The␈α
first␈α
phase␈α
of␈αthe␈α
garbage␈α
collector,␈α
called␈αthe␈α
␈↓↓marking␈α
phase␈↓,␈α
marks␈αall␈α
of␈α
the␈α
list␈αstructure
␈↓ ↓H␈↓which␈α
is␈α
currently␈α∞active.␈α
A␈α
cell␈α
is␈α∞active␈α
if␈α
it␈α∞is␈α
reachable␈α
from␈α
the␈α∞base␈α
registers␈α
by␈α∞tracing␈α
the
␈↓ ↓H␈↓␈↓↓264 static structure␈↓ %5.14␈↓
␈↓ ↓H␈↓␈↓αcar-cdr␈↓␈α∂chains.␈α∂ The␈α∂base␈α∂registers␈α∞include:␈α∂pointers␈α∂to␈α∂the␈α∂beginning␈α∞of␈α∂the␈α∂atom␈α∂table␈α∂and␈α∞the
␈↓ ↓H␈↓environment␈α
chain;␈α∞a␈α
pointer␈α∞to␈α
the␈α∞control␈α
chain␈α∞is␈α
also␈α∞included␈α
since␈α∞partial␈α
results␈α∞are␈α
stored
␈↓ ↓H␈↓there.␈α Active␈αcells␈αtherefore␈αinclude␈αall␈αthe␈αatoms␈αin␈αthe␈αatom␈αtable␈αand␈αall␈αthe␈αassociated␈αelements
␈↓ ↓H␈↓on property lists. Any partial computations which have been generated will also be marked.
␈↓ ↓H␈↓In␈α∂terms␈α∂of␈α∂our␈α∂implementation,␈α⊂we␈α∂mark␈α∂from␈α∂the␈α∂object␈α⊂list,␈α∂from␈α∂␈↓αdest␈↓,␈α∂and␈α∂from␈α⊂␈↓αcontrol␈↓␈α∂(see
␈↓ ↓H␈↓page 188).␈α∩If␈α⊃deep␈α∩binding␈α⊃is␈α∩used,␈α∩we␈α⊃mark␈α∩the␈α⊃elements␈α∩reachable␈α⊃through␈α∩␈↓αenv␈↓.␈α∩ If␈α⊃shallow
␈↓ ↓H␈↓binding␈αis␈αused,␈αthen␈αmarking␈αof␈α␈↓αoblist␈↓␈αwould␈αcapture␈αall␈αthe␈αvalues;␈αeven␈αthe␈αones␈αwhich␈αmay␈αnot
␈↓ ↓H␈↓be␈α
accessible␈α∞as␈α
λ-values.␈α∞What␈α
we␈α∞should␈α
do␈α∞instead␈α
is␈α∞mark␈α
the␈α∞non-value␈α
properties␈α∞on␈α
atoms
␈↓ ↓H␈↓using ␈↓αoblist␈↓; we then mark the values separately using the current ␈↓αenv␈↓ skeleton tree.
␈↓ ↓H␈↓A␈α∩structure␈α⊃might␈α∩be␈α∩referenced␈α⊃several␈α∩times␈α∩in␈α⊃the␈α∩marking␈α∩process,␈α⊃since␈α∩we␈α∩allow␈α⊃shared
␈↓ ↓H␈↓structure,␈α∩and␈α⊃since␈α∩the␈α⊃implementation␈α∩will␈α∩be␈α⊃referencing␈α∩structures␈α⊃referenced␈α∩by␈α∩the␈α⊃user's
␈↓ ↓H␈↓program.␈αWe␈αmust␈α
take␈αthis␈αinto␈α
account␈αsince␈αmarking␈α
of␈αan␈αalready␈α
marked␈αstructure␈αis␈α
at␈αleast
␈↓ ↓H␈↓wasteful,␈αis␈αfatal␈αif␈αthe␈αstructure␈αis␈α
self-referential.␈α Once␈αall␈αthe␈αactive␈αstructure␈αhas␈α
been␈αmarked,
␈↓ ↓H␈↓we proceed to the ␈↓↓sweep phase.␈↓
␈↓ ↓H␈↓The␈αsweep␈αphase␈αproceeds␈αlinearly␈αthrough␈αmemory,␈αcollecting␈αall␈αthose␈αcells␈αwhich␈αhave␈αnot␈αbeen
␈↓ ↓H␈↓marked␈↓π 177␈↓.␈α These␈α
unmarked␈αcells␈α
are␈αchained␈αtogether␈α
via␈αtheir␈α
␈↓αcdr␈↓-parts␈αto␈αform␈α
a␈αnew␈α
FS␈αlist.
␈↓ ↓H␈↓The␈αFS␈αpointer␈αis␈αset␈αto␈αthe␈αbeginning␈αof␈αthis␈αlist.␈α The␈αunmarked␈αcells␈αin␈αFWS␈αcomprise␈αthe␈αnew
␈↓ ↓H␈↓FWS list.
␈↓ ↓H␈↓If␈α
there␈α
is␈α
sufficient␈α
room␈α
in␈α
a␈α
full␈α
word␈α
to␈α
contain␈α
a␈α
pointer,␈α
then␈α
we␈α
chain␈α
the␈α∞words␈α
together;
␈↓ ↓H␈↓otherwise we must designate the FWS list some other way.
␈↓ ↓H␈↓Garbage␈αcollection␈αis␈αa␈αvery␈αgeneral␈αstorage␈αmanagement␈αtechnique.␈α It␈αhas␈αbecome␈αa␈αstandard␈αtool
␈↓ ↓H␈↓for implementors of complex systems. It was invented by the original LISP implementation team.
␈↓ ↓H␈↓␈↓ ∧J␈↓↓5.15 A Simple LISP Garbage Collector␈↓
␈↓ ↓H␈↓We will now write a garbage collector in LISP to mark and sweep nodes in FS and FWS␈↓π 178␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 177␈↓␈αThe␈αsweep␈αphase␈α
is␈αsometimes␈αa␈αgood␈α
place␈αto␈αunmark␈αthe␈α
marked␈αcells.␈α That␈αdepends␈αon␈α
the
␈↓ ↓H␈↓implementation.␈αIf␈αeach␈α
word␈αcarries␈αa␈α
"mark bit ␈αthen,␈αyes;␈αif␈α
the␈αmarked␈αbits␈α
are␈αall␈αlocalized␈αin␈α
a
␈↓ ↓H␈↓separate bit table (Section 7.1) then there is no advantage to doing the unmarking now.
␈↓ ↓H␈↓␈↓π 178␈↓ More complex algorithms will be discussed in Section 7.3 and on page 373.
␈↓ ↓H␈↓␈↓↓5.15␈↓ π2A Simple LISP Garbage Collector 265␈↓
␈↓ ↓H␈↓The algorithm will have three main functions:
␈↓ ↓H␈↓␈↓αinitialize[x;y]␈↓␈α
initializes␈α
the␈α
marking␈α
device␈α
for␈α
each␈α∞cell␈α
in␈α
the␈α
space␈α
between␈α
␈↓αx␈↓␈α
and␈α∞␈↓αy␈↓.␈α
␈↓αinitialize␈↓
␈↓ ↓H␈↓␈↓ βλwill␈α∞be␈α∞called␈α
twice;␈α∞once␈α∞for␈α
FS␈α∞and␈α∞once␈α
for␈α∞FWS.␈α∞ ␈↓αmark␈↓␈α
will␈α∞be␈α∞called␈α∞for␈α
each
␈↓ ↓H␈↓␈↓ βλbase␈αregister␈αwhich␈αpoints␈αto␈αactive␈αlist␈αstructure.␈α The␈αbasic␈αstructure␈αof␈α␈↓αmark␈↓␈αis:␈αif
␈↓ ↓H␈↓␈↓ βλthe␈α
word␈α
is␈αin␈α
FWS␈α
mark␈α
it␈αand␈α
return;␈α
if␈α
the␈αword␈α
has␈α
already␈α
been␈αmarked␈α
simply
␈↓ ↓H␈↓␈↓ βλreturn␈α
since␈α
we␈α
are␈α∞assured␈α
that␈α
any␈α
cells␈α∞further␈α
down␈α
the␈α
structure␈α∞have␈α
already
␈↓ ↓H␈↓␈↓ βλbeen␈αmarked.␈αOtherwise␈αthe␈αword␈αis␈αin␈αFS␈α
and␈αthus␈αhas␈αa␈α␈↓αcar␈↓␈αand␈αa␈α␈↓αcdr␈↓;␈α
mark␈αthe
␈↓ ↓H␈↓␈↓ βλword; recursively mark the ␈↓αcar␈↓; recursively mark the ␈↓αcdr␈↓.
␈↓ ↓H␈↓␈↓αmark[l]␈↓ does the actual marking of a list ␈↓αl␈↓.
␈↓ ↓H␈↓␈↓αsweep[x;y]␈↓␈α
collects␈αall␈α
inaccessible␈αcells␈α
in␈α
the␈αspace␈α
delimited␈αby␈α
␈↓αx␈↓␈α
and␈α␈↓αy␈↓.␈α
␈↓αsweep␈↓␈αwill␈α
be␈αcalled␈α
twice;
␈↓ ↓H␈↓␈↓ αXonce␈α
to␈α
generate␈α
a␈α
new␈α
free␈α
space␈α
list␈α
and␈α
once␈α
to␈α
generate␈α
a␈α
new␈α
full␈α
word␈α
space␈α
list.
␈↓ ↓H␈↓␈↓ αXElements␈α
of␈α
these␈α
free␈α
lists␈α
will␈α
be␈α
chained␈α
together␈α
by␈α
their␈α
␈↓αcdr␈↓␈α
parts.␈α The␈α
initialization
␈↓ ↓H␈↓␈↓ αXand␈αsweep␈α
phases␈αof␈α
this␈αgarbage␈αcollector␈α
are␈αvery␈α
similar␈αand,␈α
as␈αwe␈αmentioned␈α
above,
␈↓ ↓H␈↓␈↓ αXcan␈αsometimes␈αbe␈αcombined.␈α Both␈αthese␈α
phases␈αmust␈αbe␈αassured␈αof␈αreaching␈αevery␈α
node
␈↓ ↓H␈↓␈↓ αXin the space.
␈↓ ↓H␈↓These main functions use several other functions and predicates:
␈↓ ↓H␈↓␈↓αfwswrdp[x]␈↓␈αis␈αtrue␈αjust␈α
in␈αthe␈αcase␈αthat␈α
␈↓αx␈↓␈αis␈αa␈αword␈α
in␈αFWS.␈αThis␈αis␈α
used␈αas␈αone␈αof␈αthe␈α
termination
␈↓ ↓H␈↓␈↓ αhconditions of ␈↓αmark␈↓.
␈↓ ↓H␈↓␈↓αmarkA[x]␈↓ marks word ␈↓αx␈↓ as accessible.
␈↓ ↓H␈↓␈↓αmarkNA[x]␈↓ marks word ␈↓αx␈↓ as not accessible.
␈↓ ↓H␈↓␈↓αAp[x]␈↓ is true if word ␈↓αx␈↓ is marked "accessible".
␈↓ ↓H␈↓␈↓αup[x]␈↓: If ␈↓αx␈↓ is at location ␈↓
n␈↓ then ␈↓αup[x]␈↓ is location ␈↓
n+1␈↓.
␈↓ ↓H␈↓␈↓αrplacd[x;y]␈↓ modifies ␈↓αx␈↓ by replacing its ␈↓αcdr␈↓-part with ␈↓αy␈↓. The value returned is the new ␈↓αx␈↓.
␈↓ ↓H␈↓␈↓↓266 static structure␈↓ '5.15␈↓
␈↓"␈↓ ↓H␈↓
␈↓αdest␈↓
␈↓αenv␈↓
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααα⊃ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ #αβα⊃ %→ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ←$ ~ x ~ # βα→α⊃
␈↓"␈↓ ↓H␈↓
~ ~ β→ - - →⊃ εαααβαααλ ~
␈↓"␈↓ ↓H␈↓
εαααβαααλ ~ y ~ #αβ→⊃ ↓
␈↓"␈↓ ↓H␈↓
~ ~ ~ ↓ %ααα∀ααα$ ↓ ~
␈↓"␈↓ ↓H␈↓
# # # ⊂αααπααα⊃ ⊂ααααααα⊃ ~ ↓
␈↓"␈↓ ↓H␈↓
εαααβαααλ ~ ? ~ # β→ - - - →~ ? ~←$ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ %ααα∀ααα$ %ααααααα$ ~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ ↑ ↓
␈↓"␈↓ ↓H␈↓
%←ααααα←αααα←ααααα←ααααα←ααα$
␈↓"␈↓ ↓H␈↓↓␈↓ ¬CAlgorithm for ␈↓αrplacd␈↓
␈↓ ↓H␈↓Can you write ␈↓αrplacd␈↓ as a LISP function?
␈↓ ↓H␈↓αinitialize <= λ[[x;y] prog[[]
␈↓ ↓H␈↓α␈↓ β( a␈↓ βHmarkNA[x];
␈↓ ↓H␈↓α␈↓ β(␈↓ βHx ← up[x];
␈↓ ↓H␈↓α␈↓ β(␈↓ βH[eq[x;y] → return[␈↓
t␈↓α]];
␈↓ ↓H␈↓α␈↓ β(␈↓ βHgo [a]]]
␈↓ ↓H␈↓αmark <= λ[[l] [␈↓ β(Ap[l] → ␈↓
t␈↓α;
␈↓ ↓H␈↓α␈↓ β(fwswrdp[l] → markA[l];
␈↓ ↓H␈↓α␈↓ β(␈↓
t␈↓α → markA[l]; mark[car[l]]; mark[cdr[l]] ]]
␈↓ ↓H␈↓αsweep <= λ[[x;y] prog[[z]
␈↓ ↓H␈↓α␈↓ βλ a␈↓ β([not[Ap[x]] → z ← rplacd[ x;z]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ β(x ← up[x];
␈↓ ↓H␈↓α␈↓ βλ␈↓ β([eq[x;y] → return [z]];
␈↓ ↓H␈↓α␈↓ βλ␈↓ β(go[a]]]
␈↓ ↓H␈↓As␈α
indicated␈αabove,␈α
there␈αare␈α
alternatives␈α
to␈αgarbage␈α
collection.␈α If␈α
the␈αdata-structure␈α
manipulations
␈↓ ↓H␈↓are␈α∩particularly␈α⊃simple␈α∩then␈α∩leaving␈α⊃storage␈α∩management␈α∩to␈α⊃the␈α∩programmer.␈α∩ However,␈α⊃LISP
␈↓ ↓H␈↓generates␈α
very␈αintertwined␈α
structures,␈α
and␈αexplicit␈α
management␈α
is␈αnot␈α
satisfactory.␈α
There␈αis␈α
another
␈↓ ↓H␈↓way␈α⊃to␈α⊂allow␈α⊃the␈α⊃system␈α⊂to␈α⊃handle␈α⊂storage␈α⊃management.␈α⊃ First␈α⊂notice␈α⊃that␈α⊃storage␈α⊂management
␈↓ ↓H␈↓becomes␈αquite␈αsimple␈αif␈αthere␈αis␈αno␈αsharing␈αof␈αsublists.␈αThe␈αquestion␈αof␈αwhen␈αto␈αreturn␈αa␈αlist␈αto␈α
the
␈↓ ↓H␈↓free␈αspace␈αlist␈αis␈αeasily␈αsolved.␈αHowever␈αit␈αis␈αdesirable␈αto␈αshare␈αsubstructure;␈αsharing␈αcan␈αobviously
␈↓ ↓H␈↓␈↓↓5.15␈↓ π2A Simple LISP Garbage Collector 267␈↓
␈↓ ↓H␈↓save␈α∩space␈α∩and␈α∩careful␈α∩modification␈α⊃of␈α∩shared␈α∩structures␈α∩can␈α∩communicate␈α∩global␈α⊃information
␈↓ ↓H␈↓between algorithms.
␈↓ ↓H␈↓Instead␈αof␈αusing␈αa␈αgarbage␈αcollector,␈αwe␈αmight␈αassociate␈αa␈αcounter,␈αcalled␈αa␈α␈↓↓reference␈αcounter␈↓,␈αwith
␈↓ ↓H␈↓each␈α
list␈α
when␈α
it␈α
is␈α
built.␈α
In␈α
that␈α
counter␈α∞we␈α
will␈α
store␈α
the␈α
number␈α
of␈α
references␈α
to␈α
that␈α∞list.␈α
The
␈↓ ↓H␈↓counter␈αwill␈αbe␈α
initialized␈αto␈α1␈α
when␈αthe␈αlist␈α
is␈αcreated.␈α Whenever␈α
the␈αlist␈αis␈α
shared␈αwe␈αincrease␈α
the
␈↓ ↓H␈↓counter␈α∞by␈α∞1;␈α
whenever␈α∞the␈α∞list␈α∞is␈α
no␈α∞longer␈α∞to␈α
be␈α∞shared␈α∞by␈α∞some␈α
list␈α∞structure,␈α∞we␈α∞decrease␈α
the
␈↓ ↓H␈↓counter␈α
by␈α
1.␈α
When␈αthe␈α
count␈α
goes␈α
to␈α0␈α
we␈α
can␈α
put␈α
the␈αcells␈α
of␈α
the␈α
list␈αin␈α
the␈α
free␈α
space␈α
list.␈α A
␈↓ ↓H␈↓difficulty␈αwith␈αthe␈αreference␈αcounter␈αscheme␈αis␈αthe␈αinability␈αto␈αcollect␈αcircular␈αlists.␈αA␈αcircular␈αlist␈αis
␈↓ ↓H␈↓a list structure which is self-referential␈↓π 179␈↓. Consider the following sequence:
␈↓ ↓H␈↓␈↓↓1.␈↓ Manufacture a list, ␈↓αx␈↓: ␈↓αx ← (B I G M O T H E R L I S T)␈↓. Reference count is 1.
␈↓ ↓H␈↓␈↓↓2.␈↓ Circularize it: ␈↓αx ← circle[x];␈↓. Reference count is now 2.
␈↓ ↓H␈↓␈↓↓3.␈↓ Delete all references to ␈↓αx␈↓: ␈↓αx ← NIL␈↓. Reference count reverts to 1.
␈↓ ↓H␈↓The␈α
list␈αis␈α
no␈α
longer␈αreferenced,␈α
but␈αit␈α
is␈α
not␈αon␈α
the␈α
free␈αspace␈α
list,␈αand␈α
has␈α
thus␈αbeen␈α
lost␈α
to␈αthe
␈↓ ↓H␈↓system.
␈↓ ↓H␈↓Two␈αless␈αserious␈α
considerations␈αshould␈αbe␈αmentioned␈α
in␈αconjunction␈αwith␈αreference␈α
counters.␈αFirst,
␈↓ ↓H␈↓each␈α∂node␈α∂which␈α∂is␈α∂to␈α∂be␈α∂collected␈α∂with␈α∂this␈α∂scheme␈α∂must␈α∂have␈α∂an␈α∂associated␈α∂reference␈α⊂field␈α∂to
␈↓ ↓H␈↓contain␈α
the␈α
count.␈α
That␈αrequires␈α
extra␈α
space,␈α
and␈α
usually␈αimposes␈α
a␈α
maximum␈α
size␈α
for␈αthe␈α
reference
␈↓ ↓H␈↓count.␈α If␈αthat␈αmaximum␈αis␈αreached,␈αeither␈αan␈αadditional␈αspace␈αis␈αallocated,␈αor␈αthe␈αfilled␈αcount␈αmay
␈↓ ↓H␈↓never be decremented and the associated structure must be garbage collected.
␈↓ ↓H␈↓The␈α⊃second␈α⊂problem␈α⊃involves␈α⊂decrementing␈α⊃counts.␈α⊂Whenever␈α⊃a␈α⊂count␈α⊃goes␈α⊂to␈α⊃zero␈α⊃the␈α⊂counts
␈↓ ↓H␈↓associated␈α∀with␈α∀its␈α∀immediate␈α∀successors␈α∀must␈α∀also␈α∀be␈α∀decremented.␈α∀ This␈α∀process␈α∃is␈α∀applied
␈↓ ↓H␈↓recursively until non-zero counts are encountered. The bookkeeping for such a task is non-trivial.
␈↓ ↓H␈↓However␈α⊃there␈α∩are␈α⊃significant␈α∩storage␈α⊃management␈α∩problems␈α⊃which␈α∩are␈α⊃amenable␈α∩to␈α⊃reference
␈↓ ↓H␈↓counting.␈α
Parts␈α
of␈α
the␈α
implementation␈α
of␈α∞LISP␈α
systems␈α
can␈α
profitably␈α
use␈α
reference␈α∞counting.␈α
We
␈↓ ↓H␈↓will␈α∩discuss␈α⊃some␈α∩of␈α⊃these␈α∩aspects␈α⊃in␈α∩Section 5.20.␈α⊃For␈α∩an␈α⊃excellent␈α∩discussion␈α⊃and␈α∩analysis␈α⊃of
␈↓ ↓H␈↓storage management schemes see [Mul 76].
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I␈α∂This␈α∞problem␈α∂deals␈α∂with␈α∞what␈α∂is␈α∂known␈α∞in␈α∂LISP␈α∞as␈α∂␈↓↓hash␈α∂consing␈↓␈α∞([Got 74]).␈α∂ We␈α∂have␈α∞been
␈↓ ↓H␈↓storing␈α
atoms␈α
uniquely,␈α
but␈α
it␈α
should␈α
be␈α
clear␈α
from␈α
the␈α
behavior␈α
of␈α
␈↓αcons␈↓␈α
that␈α
non-atomic␈αS-exprs
␈↓ ↓H␈↓are␈α
␈↓↓not␈↓␈α∞stored␈α
uniquely.␈α
Storing␈α∞single␈α
copies␈α
of␈α∞any␈α
S-expr␈α
would␈α∞save␈α
space.␈α
For␈α∞example,␈α
the
␈↓ ↓H␈↓non-atomic␈α∂structure␈α∂of␈α∂␈↓α((A␈α∂.␈α⊂B).(A␈α∂.␈α∂B))␈↓␈α∂could␈α∂be␈α⊂represented␈α∂with␈α∂two␈α∂cells␈α∂rather␈α⊂than␈α∂three.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 179␈↓␈α
LISP␈α1␈α
([McC 60])␈α
disallowed␈αcircular␈α
list,␈αbut␈α
succeeding␈α
LISP␈αdialects␈α
have␈αallowed␈α
arbitrary
␈↓ ↓H␈↓binary structure.
␈↓ ↓H␈↓␈↓↓268 static structure␈↓ '5.15␈↓
␈↓ ↓H␈↓Unique␈αstorage␈αis␈αnot␈αwithout␈αits␈αdifficulties.␈αWhat␈αproblems␈αdo␈αyou␈αforesee␈αin␈αimplementing␈αsuch
␈↓ ↓H␈↓a scheme?
␈↓ ↓H␈↓II␈α⊂We␈α⊂said␈α⊂on␈α⊃page 248␈α⊂that␈α⊂many␈α⊂LISP␈α⊂computations␈α⊃generate␈α⊂list␈α⊂structure␈α⊂rather␈α⊃than␈α⊂true
␈↓ ↓H␈↓LISP-trees. Give an example.
␈↓ ↓H␈↓III␈αCan␈αyou␈αwrite␈αa␈αLISP␈αfunction␈α␈↓αcircle␈α<=␈αλ[[x]␈α...]␈↓␈αwhich␈αwill␈αtake␈αa␈αlist␈α␈↓αx␈↓␈αand␈αmake␈α
it␈αcircular.
␈↓ ↓H␈↓Thus:
␈↓"␈↓ ↓H␈↓
⊂ααααααααααααα←ααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
⊂αααααααααπααα⊃ ⊂αααααπααα⊃ ↓ ⊂ααααπααα⊃ ⊂αααααααπααα⊃ ↑
␈↓"␈↓ ↓H␈↓
~ NOTHING ~ #αβα→~ CAN ~ #αβα∀→~ GO ~ #αβα→~ WRONG ~ #αβ→$
␈↓"␈↓ ↓H␈↓
%ααααααααα∀ααα$ %ααααα∀ααα$ %αααα∀ααα$ %ααααααα∀ααα$
␈↓ ↓H␈↓This␈α∞list␈α∞is␈α∞circular␈α∞on␈α∞its␈α∞"last␈α∂two"␈α∞elements.␈α∞ Printing␈α∞such␈α∞structures␈α∞is␈α∞not␈α∞possible␈α∂using␈α∞the
␈↓ ↓H␈↓␈↓αprint␈↓ function.
␈↓ ↓H␈↓IV␈α→What␈α→LISP␈α→operations␈α→generate␈α→such␈α→intertwined␈α→structures␈α→that␈α→a␈α→reference␈α→counter
␈↓ ↓H␈↓implementation would be infeasible?
␈↓ ↓H␈↓␈↓↓5.16␈↓ ¬jA Review of the Structure of the LISP Machine 269␈↓
␈↓ ↓H␈↓␈↓ βf␈↓↓5.16 A Review of the Structure of the LISP Machine␈↓
␈↓ ↓H␈↓We␈αhave␈αa␈αgood␈αportion␈αof␈αthe␈αstorage␈α
conventions␈αfor␈αLISP␈αset␈αout.␈α A␈αdifficult␈αarea␈αinvolves␈α
the
␈↓ ↓H␈↓organization␈α⊂of␈α∂the␈α⊂data␈α⊂structures␈α∂to␈α⊂perform␈α∂the␈α⊂correct␈α⊂binding␈α∂and␈α⊂unbinding␈α⊂of␈α∂variables.
␈↓ ↓H␈↓Before we tackle that, we give a diagram showing the basic structure of LISP memory.
␈↓"␈↓ ↓H␈↓
⊂αααααααααααααααααααααααααααααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
~␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ ### THE SUBCONSCIOUS ###␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ ␈↓αeval␈↓
and friends␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ ␈↓αread␈↓
and ␈↓αprint␈↓
␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ the garbage collector␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ the base registers for marking;␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ these include:␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ FS pointer␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ FWS pointer␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ atom table(␈↓αOBLIST␈↓
) pointer␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ registers for partial results␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ ␈↓αdest, control␈↓
␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ the access chain␈↓ πX~
␈↓"␈↓ ↓H␈↓
~␈↓ πX~
␈↓"␈↓ ↓H␈↓
εααααααααααααααααααααααααααααααααααααααααλ
␈↓"␈↓ ↓H␈↓
~␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ ### POINTER SPACE ###␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ the free space list␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ those parts of S-exprs containing␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ ␈↓αcar␈↓
- and ␈↓αcdr␈↓
-parts.␈↓ πX~
␈↓"␈↓ ↓H␈↓
~␈↓ πX~
␈↓"␈↓ ↓H␈↓
εααααααααααααααααααααααααααααααααααααααααλ
␈↓"␈↓ ↓H␈↓
~␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ ### FULL WORD SPACE ###␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ the full word space list␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ atom print names␈↓ πX~
␈↓"␈↓ ↓H␈↓
~ numbers␈↓ πX~
␈↓"␈↓ ↓H␈↓
~␈↓ πX~
␈↓"␈↓ ↓H␈↓
%αααααααααααααααααααααααααααααααααααααααα$
␈↓ ↓H␈↓␈↓ ¬~␈↓↓Structure of LISP memory␈↓
␈↓ ↓H␈↓␈↓ ∧l␈↓↓5.17 Implementations of Binding␈↓
␈↓ ↓H␈↓In␈α
Section 3.5␈αand␈α
Section 3.11␈αwe␈α
discussed␈αdeep␈α
binding␈αand␈α
shallow␈αbinding␈α
respectively.␈αThat
␈↓ ↓H␈↓discussion␈α∞took␈α
place␈α∞at␈α∞a␈α
reasonably␈α∞abstract␈α∞level.␈α
The␈α∞next␈α∞few␈α
sections␈α∞discuss␈α∞these␈α
binding
␈↓ ↓H␈↓implementations␈α
in␈α
more␈α
detail.␈α
We␈α
first␈αdiscuss␈α
some␈α
of␈α
the␈α
possible␈α
pitfalls␈α
in␈αthe␈α
implementation
␈↓ ↓H␈↓of␈α
LISP;␈αthen␈α
we␈αgive␈α
deep␈α
and␈αshallow␈α
implementations␈αfor␈α
an␈α
important␈αsubset␈α
of␈αLISP.␈α
Finally,
␈↓ ↓H␈↓␈↓↓270 static structure␈↓ (5.17␈↓
␈↓ ↓H␈↓we␈α∩discuss␈α⊃some␈α∩of␈α∩the␈α⊃methods␈α∩available␈α∩for␈α⊃implementing␈α∩the␈α∩full␈α⊃language␈α∩in␈α∩an␈α⊃efficient
␈↓ ↓H␈↓manner.
␈↓ ↓H␈↓Though␈α⊂much␈α⊂of␈α⊃this␈α⊂discussion␈α⊂deals␈α⊃with␈α⊂the␈α⊂binding␈α⊂stategies␈α⊃of␈α⊂LISP,␈α⊂and␈α⊃therefore␈α⊂with
␈↓ ↓H␈↓control␈αstructure,␈αwe␈α
are␈αrestricting␈αourselves␈α
to␈αthe␈αdata␈α
structure␈αrequirements.␈αThe␈α
next␈αchapter
␈↓ ↓H␈↓discusses how the control structures of LISP implementations manipulate these data structures.
␈↓ ↓H␈↓Consider the evaluation of a form:
␈↓ ↓H␈↓α␈↓ ¬Zf[a␈↓β1␈↓α; ... ;a␈↓βn␈↓α]␈↓ where:
␈↓ ↓H␈↓␈↓α␈↓ ∧hf <= λ[[x␈↓β1␈↓α; ... ;x␈↓βn␈↓α] ... g[ ... ] ... ;i[ ... ]],
␈↓ ↓H␈↓α␈↓ ¬≤g <= λ[[ ... ] ... h[ ... ] ], ␈↓and ␈↓α
␈↓ ↓H␈↓α␈↓ ¬Ii <= λ[[ ... ] ... j[ ... ] ]
␈↓ ↓H␈↓Typically␈αa␈αpicture␈α
like␈αthe␈αfollowing␈α
occurs,␈αwhere␈αthe␈α
instance␈αof␈αfunction␈α
name␈αmeans␈αa␈αblock␈α
of
␈↓ ↓H␈↓λ-bindings necessary to begin evaluation of that function:
␈↓"␈↓ ↓H␈↓
⊂ααα⊃ ⊂ααα⊃
␈↓"␈↓ ↓H␈↓
~ h ~ ~ j ~
␈↓"␈↓ ↓H␈↓
⊂ααα⊃ εαααλ ⊂ααα⊃ ⊂ααα⊃ εαααλ ...
␈↓"␈↓ ↓H␈↓
~ g ~ ~ g ~ ~ g ~ ~ i ~ ~ i ~
␈↓"␈↓ ↓H␈↓
⊂ααα⊃ εαααλ εαααλ εαααλ ⊂ααα⊃ εαααλ εαααλ ...
␈↓"␈↓ ↓H␈↓
~ f ~ ~ f ~ ~ f ~ ~ f ~ ~ f ~ ~ f ~ ~ f ~
␈↓"␈↓ ↓H␈↓
%ααα$ %ααα$ %ααα$ %ααα$ %ααα$ %ααα$ %ααα$
␈↓ ↓H␈↓We␈α∞build␈α∞up␈α∞a␈α∞stack␈α∞of␈α
λ-binding␈α∞blocks␈α∞as␈α∞we␈α∞continue␈α∞to␈α
enter␈α∞procedures,␈α∞and␈α∞as␈α∞we␈α∞leave␈α
a
␈↓ ↓H␈↓procedure␈α
we␈αremove␈α
that␈α
block␈αof␈α
bindings␈α
from␈αthe␈α
stack.␈α
When␈αwe␈α
wish␈α
to␈αknow␈α
the␈α
value␈αof␈α
a
␈↓ ↓H␈↓variable␈αwe␈αlook␈αdown␈αthe␈αstack␈αfor␈αthe␈αfirst␈αoccurrence␈αof␈αthat␈αvariable;␈αthe␈αassociated␈αbinding␈αis
␈↓ ↓H␈↓the␈α∩desired␈α∩value.␈α∩ LISP␈α∩allows␈α∪functional␈α∩arguments␈α∩and␈α∩functional␈α∩values.␈α∪These␈α∩constructs
␈↓ ↓H␈↓require modification of the behavior modeled in the simple blocks world.
␈↓ ↓H␈↓When␈αwe␈αrecognize␈αa␈αfunctional␈αargument,␈αwe␈αnote␈αthe␈αblock␈αwhich␈αis␈αcurrently␈αon␈αthe␈αtop␈αof␈αthe
␈↓ ↓H␈↓stack.␈α⊂When␈α⊂we␈α⊂apply␈α∂that␈α⊂functional␈α⊂argument,␈α⊂intervening␈α∂blocks␈α⊂will␈α⊂have␈α⊂been␈α⊂stacked;␈α∂we
␈↓ ↓H␈↓change␈αthe␈αenvironment␈αsuch␈αthat␈αthe␈αlookup␈α
of␈αnon-local␈αvariables␈αtakes␈αplace␈αbeginning␈αwith␈α
the
␈↓ ↓H␈↓saved block, rather than with the top of the stack.
␈↓ ↓H␈↓However,␈αif␈α␈↓αh␈↓␈αsay,␈αgenerated␈αa␈αfunctional␈αvalue␈αwhich␈αis␈αto␈αbe␈αapplied␈αin␈αthe␈αcontext␈αof␈α␈↓αj␈↓␈αthen␈αwe
␈↓ ↓H␈↓must␈α∂retain␈α∂those␈α∞values␈α∂in␈α∂the␈α∞␈↓αf-g-h␈↓␈α∂stack␈α∂in␈α∞such␈α∂a␈α∂way␈α∞that␈α∂they␈α∂may␈α∞be␈α∂used␈α∂to␈α∂restore␈α∞the
␈↓ ↓H␈↓enviroment when we desire to apply the functional value in the ␈↓αf-i-j␈↓ stack.
␈↓"␈↓ ↓H␈↓
⊂ααα⊃ ⊂ααα⊃
␈↓"␈↓ ↓H␈↓
↑ ~ h ~ ~ j ~ ~
␈↓"␈↓ ↓H␈↓
~ εαααλ εαααλ ↓
␈↓"␈↓ ↓H␈↓
bind ~ ~ g ~ ~ i ~ ~ unbind
␈↓"␈↓ ↓H␈↓
↑ εααα∀αα∀αααλ ↓
␈↓"␈↓ ↓H␈↓
~ ~ f ~ ↓
␈↓"␈↓ ↓H␈↓
%αααααααααα$
␈↓ ↓H␈↓We␈αwill␈αdiscuss␈αdata␈αstructure␈αrequirements␈αfor␈αimplementation␈αof␈αthese␈αthree␈αLISP␈αsubsets:␈αsimple
␈↓ ↓H␈↓function application, functional arguments, and functional values.
␈↓ ↓H␈↓␈↓↓5.17␈↓ πvImplementations of Binding 271␈↓
␈↓ ↓H␈↓The␈αmechanism␈αwhich␈αwe␈αdescribed␈αin␈αthe␈αinitial␈αblocks␈αmodel␈αoccurs␈αquite␈αnaturally␈αin␈αcomputer
␈↓ ↓H␈↓science.␈αIt␈αis␈αcalled␈αa␈α␈↓↓stack␈↓␈↓π 180␈↓.␈α The␈αimportant␈αcharacteristics␈αof␈αstacks␈αare␈αthat␈αthey␈αare␈αlists␈αsuch
␈↓ ↓H␈↓that additions and deletions can only be made at the front of the list.
␈↓ ↓H␈↓What␈αis␈αof␈α
interest␈αto␈αus␈α
now␈αis␈αthat␈αstacks␈α
have␈αa␈αparticularly␈α
efficient␈αimplementation.␈αDue␈αto␈α
the
␈↓ ↓H␈↓very␈α⊂regular␈α⊂way␈α⊂in␈α⊂which␈α⊂stacks␈α⊃are␈α⊂manipulated,␈α⊂the␈α⊂linked␈α⊂allocation␈α⊂implementation␈α⊃is␈α⊂not
␈↓ ↓H␈↓usually␈↓π 181␈↓ necessary. Instead a stack can be implemented as:
␈↓ ↓H␈↓␈↓ αh␈↓↓1.␈↓ A sequence of contiguous locations
␈↓ ↓H␈↓␈↓ αh␈↓↓2.␈↓ A pointer initialized to point ␈↓↓before␈↓ the first of these locations.
␈↓ ↓H␈↓␈↓ αh␈↓↓3.␈↓␈αAn␈αoperation,␈αtypically␈αcalled␈α␈↓↓push␈↓␈αwhich␈αplaces␈αa␈αnew␈αobject␈αin␈αthe␈αstack.␈αThis␈αcan
␈↓ ↓H␈↓␈↓ αhbe␈α∂accomplished␈α∂by␈α∂adding␈α∂1␈α∂to␈α∂the␈α∂value␈α∂of␈α∂the␈α∂stack␈α∂pointer,␈α∂and␈α∂then␈α∂putting␈α∞a
␈↓ ↓H␈↓␈↓ αhrepresentation of the object in the cell currently referenced by the pointer.
␈↓ ↓H␈↓␈↓ αh␈↓↓4.␈↓␈αAn␈αoperation␈α
called␈α␈↓↓pop␈↓␈αwhich␈αgets␈α
the␈αfirst␈αvalue␈αin␈α
the␈αstack␈αand␈αthen␈α
decrements
␈↓ ↓H␈↓␈↓ αhthe pointer by 1.
␈↓ ↓H␈↓␈↓ αh␈↓↓5.␈↓␈αThough␈αthe␈α
abstract␈αstructure␈αof␈α
a␈αstack␈αdoes␈αnot␈α
involve␈αlimitations␈αon␈α
the␈αlength
␈↓ ↓H␈↓␈↓ αhof␈αstack-space,␈αany␈αrepresentation␈αshould␈αinclude␈αtechniques␈αfor␈αassuring␈αthat␈αthe␈αstack
␈↓ ↓H␈↓␈↓ αhpointer stays within its allotted space. See the preceding footnote.
␈↓ ↓H␈↓Notice␈αthat␈αthe␈α␈↓αconcat␈↓␈αoperation␈αcan␈αbe␈αinterpreted␈αas␈α␈↓↓pushing␈↓␈αand␈αthe␈α␈↓αrest␈↓␈αoperation␈αas␈α␈↓↓popping␈↓.
␈↓ ↓H␈↓Indeed␈α∞our␈α∞earlier␈α∞manipulations␈α∞of␈α∞symbol␈α∞tables␈α∞effectively␈α∞used␈α∞such␈α∞stack␈α∞operations.␈α∞This␈α∞is
␈↓ ↓H␈↓particularly apparent in the representation of symbol tables given on page 110.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 180␈↓␈α
Stacks␈αare␈α
closely␈αrelated␈α
to␈αa␈α
theoretical␈αdevice␈α
called␈αa␈α
push-down␈αautomaton.␈α
There,␈αonly␈α
the
␈↓ ↓H␈↓top␈α∩element␈α⊃of␈α∩the␈α∩stack␈α⊃is␈α∩accessible.␈α⊃We␈α∩take␈α∩a␈α⊃more␈α∩pragmatic␈α⊃position,␈α∩allowing␈α∩access␈α⊃to
␈↓ ↓H␈↓elements␈α∞within␈α∞the␈α∂stack,␈α∞and␈α∞indeed␈α∂modification␈α∞of␈α∞elements␈α∞within␈α∂the␈α∞stack;␈α∞but␈α∂removal␈α∞of
␈↓ ↓H␈↓elements␈α∞from␈α∞within␈α∂the␈α∞stack␈α∞is␈α∞not␈α∂allowed.␈α∞To␈α∞remove␈α∞an␈α∂element,␈α∞we␈α∞must␈α∞first␈α∂remove␈α∞the
␈↓ ↓H␈↓elements above it.
␈↓ ↓H␈↓␈↓π 181␈↓␈αThe␈αtypical␈αmodel␈αfor␈αa␈αstack␈αis␈αa␈αcontguous␈αblock␈αof␈αmemory␈αbut␈αthat␈αignores␈αthe␈αquestion␈αof
␈↓ ↓H␈↓exceeding␈α
the␈α
bounds␈α∞of␈α
that␈α
memory␈α∞allocation.␈α
A␈α
stack␈α
can␈α∞be␈α
implemented␈α
in␈α∞a␈α
discontinuous
␈↓ ↓H␈↓fashion␈α([Bis 74])␈αas␈αlong␈αas␈αthe␈αstack␈αmanipulating␈αfunctions␈αare␈αable␈αto␈αcope␈αwith␈αsuch␈αbehavior.
␈↓ ↓H␈↓The degenerate case of such discontinuous stacks is a linked allocation scheme.
␈↓ ↓H␈↓␈↓↓272 static structure␈↓ (5.17␈↓
␈↓ ↓H␈↓We will discuss the binding process in terms of a sequence of three events:
␈↓ ↓H␈↓␈↓↓1.␈↓.␈α␈↓αbind␈↓␈αdescribes␈αwhat␈αthe␈αimplementation␈αdoes␈αwhen␈αwe␈αare␈αready␈αto␈αcall␈αa␈αprocedure.␈αThe␈αactual
␈↓ ↓H␈↓␈↓ α8parameters␈αare␈αevaluated␈αand␈αwe␈αare␈αready␈αto␈αadd␈αthem␈αto␈αthe␈αenvironment␈αand␈αevaluate
␈↓ ↓H␈↓␈↓ α8the body of the procedure.
␈↓ ↓H␈↓␈↓↓2.␈↓ ␈↓αlookup␈↓ will determine how values are located in the current environment.
␈↓ ↓H␈↓␈↓↓3.␈↓ ␈↓αunbind␈↓ will describe what has to be done as we prepare to exit from a procedure.
␈↓ ↓H␈↓␈↓ ∧!␈↓↓5.18 Stack Implementation of Deep Binding␈↓
␈↓ ↓H␈↓The␈α∂stack␈α∞implementation␈α∂of␈α∂simple␈α∞function␈α∂application␈α∂is␈α∞a␈α∂straightforward␈α∂implementation␈α∞of
␈↓ ↓H␈↓our␈αblocks␈α
picture.␈α We␈α
have␈αtwo␈α
stacks␈αwhich␈α
operate␈αsynchronously.␈α
One␈αstack␈α
is␈αcalled␈αthe␈α
␈↓↓name
␈↓ ↓H␈↓↓stack␈↓;␈α
the␈α
other␈α
is␈α
called␈α
the␈α
␈↓↓value␈α
stack␈↓.␈α
The␈α
name␈α
stack␈α
maintains␈α
the␈α
λ-variables␈α(and␈α
generated
␈↓ ↓H␈↓names,␈αif␈α
a␈αprimitive␈α
is␈αcalled).␈α
The␈αtop␈α
of␈αthe␈α
name␈αstack␈α
defines␈αthe␈α
origin␈αof␈α
the␈αenvironment.
␈↓ ↓H␈↓When␈α
the␈α
value␈αof␈α
a␈α
variable␈αis␈α
requested␈α
␈↓αlookup␈↓␈αproceeds␈α
down␈α
the␈αname␈α
stack,␈α
looking␈α
for␈αthe
␈↓ ↓H␈↓first␈αoccurrence␈αof␈αthe␈αvariable.␈αThe␈αcorresponding␈αposition␈αin␈αthe␈αvalue␈αstack␈αcontains␈αthe␈αdesired
␈↓ ↓H␈↓value.
␈↓ ↓H␈↓When␈α∞we␈α
recognize␈α∞a␈α
function␈α∞application,␈α
we␈α∞begin␈α
the␈α∞evaluation␈α
of␈α∞the␈α
actual␈α∞parameters.␈α
As
␈↓ ↓H␈↓each␈α∞parameter␈α∂is␈α∞evaluated,␈α∞the␈α∂result␈α∞is␈α∞pushed␈α∂into␈α∞the␈α∞value␈α∂stack.␈α∞When␈α∞all␈α∂the␈α∞parameters
␈↓ ↓H␈↓have␈α⊂been␈α⊂evaluated,␈α⊂we␈α∂are␈α⊂ready␈α⊂to␈α⊂evaluate␈α∂the␈α⊂body␈α⊂of␈α⊂the␈α∂expression.␈α⊂At␈α⊂that␈α⊂point␈α∂␈↓αbind␈↓
␈↓ ↓H␈↓pushes␈αthe␈αλ-variables␈αonto␈αthe␈αname␈αstack.␈α When␈αwe␈αcomplete␈αthe␈αevaluation␈αof␈αthe␈αbody␈αof␈αthe
␈↓ ↓H␈↓expression␈α∂␈↓αunbind␈↓␈α∂pops␈α∂the␈α∞λ-variables␈α∂off␈α∂of␈α∂the␈α∞name␈α∂stack,␈α∂and␈α∂pops␈α∞their␈α∂values␈α∂off␈α∂of␈α∞the
␈↓ ↓H␈↓value stack.
␈↓ ↓H␈↓Since␈αthe␈αλ-variables␈α
leave␈αthe␈αstack␈α
as␈αa␈αgroup␈αwe␈α
can␈αsometimes␈αspeed␈α
things␈αup␈αby␈αstoring␈α
block
␈↓ ↓H␈↓sizes␈α
in␈αthe␈α
stack.␈αAlso␈α
the␈α
word␈αsize␈α
of␈αthe␈α
machine␈αmay␈α
allow␈α
using␈αone␈α
stack␈αfor␈α
both␈αnames␈α
and
␈↓ ↓H␈↓values. For example:
␈↓"␈↓ ↓H␈↓
⊂ααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
~ #ααα→ααβ→⊃
␈↓"␈↓ ↓H␈↓
εαααααααπαααααλ ↓
␈↓"␈↓ ↓H␈↓
~ namen ~ valn~ ~
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
# # # ↓
␈↓"␈↓ ↓H␈↓
~ name2 ~ val2~ ~
␈↓"␈↓ ↓H␈↓
εαααααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
~ name1 ~ val1~ ↓
␈↓"␈↓ ↓H␈↓
εααααααα∀αααααλ ~
␈↓"␈↓ ↓H␈↓
~ ~←$
␈↓"␈↓ ↓H␈↓
~ #ααα→ααβ→⊃
␈↓"␈↓ ↓H␈↓
↓
␈↓ ↓H␈↓␈↓↓5.18␈↓ εaStack Implementation of Deep Binding 273␈↓
␈↓ ↓H␈↓Where␈α∞␈↓
val1␈↓␈α∞is␈α∞furthest␈α
down␈α∞the␈α∞stack␈α∞since␈α
it␈α∞was␈α∞pushed␈α∞on␈α
first,␈α∞and␈α∞where␈α∞all␈α∞references␈α
to
␈↓ ↓H␈↓␈↓
namei␈↓␈α
and␈α
␈↓
vali␈↓␈α∞are␈α
really␈α
pointers␈α∞to␈α
to␈α
appropriate␈α
S-expressions␈α∞(atoms␈α
or␈α
dotted␈α∞pairs).␈α
The
␈↓ ↓H␈↓"back␈αpointer"␈α
is␈αused␈α
for␈αremoving␈αblocks␈α
of␈αbindings,␈α
but␈αit␈αis␈α
also␈αa␈α
representation␈αof␈αthe␈α
control
␈↓ ↓H␈↓link discussed in Section 3.8.
␈↓ ↓H␈↓A␈α∞slight␈α∞modification␈α∞of␈α∂this␈α∞scheme␈α∞is␈α∞sufficient␈α∂to␈α∞support␈α∞evaluation␈α∞of␈α∂functional␈α∞arguments.
␈↓ ↓H␈↓The␈α∂additional␈α∂piece␈α∞of␈α∂information␈α∂guides␈α∞␈↓αlookup␈↓␈α∂in␈α∂its␈α∞search␈α∂for␈α∂the␈α∞next␈α∂block␈α∂of␈α∞bindings.
␈↓ ↓H␈↓Instead␈αof␈αproceeding␈αlinearly␈αdown␈αthe␈αstack,␈α␈↓αlookup␈↓␈αproceeds␈αlinearly␈αthrough␈αa␈αblock␈αand␈αat␈αthe
␈↓ ↓H␈↓end␈α
of␈α
each␈α
block␈α∞is␈α
information␈α
telling␈α
␈↓αlookup␈↓␈α∞where␈α
the␈α
next␈α
block␈α∞of␈α
bindings␈α
is␈α
to␈α∞be␈α
found.
␈↓ ↓H␈↓Recall that information is called the access link (Section 3.8).
␈↓"␈↓ ↓H␈↓
⊂ααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
⊂←β←αα# #αα→β→⊃
␈↓"␈↓ ↓H␈↓
↓ εαααααααπαααααλ ↓
␈↓"␈↓ ↓H␈↓
~ ~ namen ~ valn~ ~
␈↓"␈↓ ↓H␈↓
~ εαααααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
access links ↓ # # # ↓ control links
␈↓"␈↓ ↓H␈↓
~ ~ name2 ~ val2~ ~
␈↓"␈↓ ↓H␈↓
~ εαααααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
↓ ~ name1 ~ val1~ ↓
␈↓"␈↓ ↓H␈↓
~ εααααααα∀αααααλ ~
␈↓"␈↓ ↓H␈↓
%→~ ~←$
␈↓"␈↓ ↓H␈↓
⊂←β←αα# #αα→β→⊃
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓ ↓H␈↓In␈α⊂the␈α⊂majority␈α⊂of␈α⊂cases,␈α⊂the␈α∂access␈α⊂link␈α⊂points␈α⊂at␈α⊂the␈α⊂next␈α∂block␈α⊂down␈α⊂the␈α⊂stack.␈α⊂ The␈α⊂use␈α∂of
␈↓ ↓H␈↓functional␈α↔arguments␈α↔will␈α↔generate␈α↔an␈α↔access␈α↔link,␈α↔pointing␈α↔further␈α↔down␈α↔the␈α↔stack.␈α⊗ The
␈↓ ↓H␈↓␈↓αfunction␈↓-construct␈αis␈αresponsible␈α
for␈αsaving␈αthe␈α
binding␈αenvironment.␈αIn␈α
this␈αimplementation␈αthat␈α
is
␈↓ ↓H␈↓accomplished␈α∩by␈α∩saving␈α∩a␈α∩pointer␈α∩to␈α∩the␈α⊃current␈α∩top␈α∩of␈α∩the␈α∩name␈α∩stack.␈α∩ When␈α∩a␈α⊃functional
␈↓ ↓H␈↓argument␈α
is␈α
applied,␈α
the␈α
access␈α
link␈α
will␈α
be␈α
set␈α
to␈α
the␈α
binding␈α
environment␈α
(page 132).␈α
Since␈α
we␈α
are
␈↓ ↓H␈↓dealing␈αwith␈αfunctional␈αarguments,␈αwe␈αare␈αassured␈αthat␈αthe␈αapplication␈αof␈αthat␈αargument␈αwill␈αoccur
␈↓ ↓H␈↓within␈α
an␈α
expression␈α∞which␈α
dynamically␈α
surrounds␈α
the␈α∞creation␈α
of␈α
the␈α
functional␈α∞argument.␈α
This
␈↓ ↓H␈↓means␈α
that␈αour␈α
environment␈αpointer␈α
will␈αindeed␈α
be␈α
a␈αpointer␈α
down␈αthe␈α
stack.␈αThe␈α
use␈αof␈α
functional
␈↓ ↓H␈↓values␈α∀invalidates␈α∀that␈α∀assumption.␈α∀ Before␈α∀examining␈α∀that␈α∀problem␈α∀we␈α∀will␈α∀discuss␈α∀shallow
␈↓ ↓H␈↓binding for the same LISP subsets.
␈↓ ↓H␈↓␈↓ ∧∂␈↓↓5.19 Stack Implementation of Shallow Binding␈↓
␈↓ ↓H␈↓In␈α
this␈α
section␈α∞we␈α
again␈α
restrict␈α
ourselves␈α∞to␈α
a␈α
stack␈α
implementation␈α∞of␈α
the␈α
enviroment␈α∞tree.␈α
This
␈↓ ↓H␈↓will␈α∪allow␈α∪us␈α∩to␈α∪discuss␈α∪implementations␈α∩of␈α∪simple␈α∪function␈α∩application␈α∪as␈α∪well␈α∪as␈α∩functional
␈↓ ↓H␈↓arguments. The more general case of functional values will be postponed util the next section.
␈↓ ↓H␈↓A␈α∂stack␈α∞implementation␈α∂of␈α∞shallow␈α∂binding␈α∂allows␈α∞some␈α∂elegant␈α∞economies.␈α∂ We␈α∞can␈α∂use␈α∂a␈α∞stack
␈↓ ↓H␈↓implementation␈αfor␈αthe␈αfirst␈αshallow␈αbinder␈αof␈αSection 3.11.␈α There␈αwe␈αhad␈αa␈αcollection␈αof␈αbindings
␈↓ ↓H␈↓associated␈αwith␈α
the␈αidentifier.␈α Without␈α
loss␈αof␈α
generality,␈αwe␈αcan␈α
organize␈α␈↓αmkenv␈↓␈α
such␈αthat␈αthe␈α
new
␈↓ ↓H␈↓␈↓↓274 static structure␈↓ (5.19␈↓
␈↓ ↓H␈↓binding␈αis␈αadded␈αin␈αfront␈αof␈αany␈αprevious␈α
binding.␈α Now␈αif␈αwe␈αare␈αonly␈αevaluating␈αsimple␈α
function
␈↓ ↓H␈↓applications,␈α
␈↓αlookup␈↓␈α∞will␈α
find␈α
the␈α∞desired␈α
binding␈α
provided␈α∞the␈α
unbinding␈α
operation␈α∞removes␈α
the
␈↓ ↓H␈↓first␈α
binding␈αas␈α
it␈αexits␈α
the␈αprocedure.␈α
In␈αthis␈α
way,␈αbinding␈α
and␈αunbinding␈α
act␈αon␈α
the␈αvalue␈α
entries
␈↓ ↓H␈↓in␈αa␈αstack-like␈α
fashion.␈α Instead␈αof␈α
associating␈αa␈αseparate␈α
stack␈αwith␈αeach␈α
variable␈αand␈αaccessing␈α
the
␈↓ ↓H␈↓value␈αthrough␈αthe␈α
top␈αof␈αthe␈αstack,␈α
we␈αassociate␈αa␈α
single␈αvalue␈αcell␈αwith␈α
each␈αvariable␈αand␈αstore␈α
the
␈↓ ↓H␈↓saved␈α
values␈α
of␈αall␈α
variables␈α
on␈α
a␈αcommon␈α
stack.␈α
The␈α
"shallowest"␈αof␈α
the␈α
shallow␈α
schemes,␈αusing
␈↓ ↓H␈↓only␈α∩the␈α∩value␈α∩cell,␈α∩can␈α∩also␈α∩be␈α∩extended␈α∩to␈α∩handle␈α∩the␈α∩most␈α∩general␈α∩uses␈α∩of␈α∪␈↓αfunction␈↓.␈α∩ The
␈↓ ↓H␈↓implementation is intricate and so we will spend most of this section on that discussion.
␈↓ ↓H␈↓The␈αimplementation␈αof␈α
␈↓αlookup␈↓␈αwill␈αbe␈α
simple␈αfor␈αeither␈α
shallow␈αscheme:␈αtake␈α
the␈αvalue␈αin␈αthe␈α
value
␈↓ ↓H␈↓cell.␈α
Since␈α
the␈α
the␈α
value␈α
cell␈α
will␈α
be␈α
maintained␈α
to␈α
␈↓↓always␈↓␈α
contain␈α
the␈α
proper␈α
binding␈α
of␈αa␈α
variable,
␈↓ ↓H␈↓the␈αdistinction␈αbetween␈αlocal␈αand␈αnon-local␈αvariables␈αvanishes.␈αThe␈αcontents␈αof␈αthe␈αvalue␈αcell␈αis␈α␈↓↓the␈↓
␈↓ ↓H␈↓current value for any variable.
␈↓ ↓H␈↓We␈αfirst␈αreview␈αthe␈αprocess␈αof␈αshallow␈αbinding␈αwith␈αthe␈αvalue␈αcell,␈αincluding␈αthe␈αdetails␈αwe␈αadded
␈↓ ↓H␈↓in␈αSection 4.6.␈α
When␈αan␈α
application␈αis␈α
recognized␈αwe␈αallocate␈α
a␈αblock␈α
to␈αcontain␈α
the␈αvalues␈α
of␈αthe
␈↓ ↓H␈↓actual␈αparameters;␈αthat␈αis␈αthe␈α␈↓αdest␈↓␈αblock.␈αAs␈α
the␈αarguments␈αare␈αevaluated,␈αthe␈αresults␈αare␈αsent␈αto␈α
the
␈↓ ↓H␈↓appropriate␈α∂slots␈α∂in␈α∂the␈α∂␈↓αdest␈↓␈α∂block␈↓π 182␈↓.␈α∂When␈α⊂all␈α∂the␈α∂arguments␈α∂are␈α∂evaluated,␈α∂we␈α∂link␈α⊂the␈α∂␈↓αdest␈↓
␈↓ ↓H␈↓block␈α∞onto␈α
the␈α∞front␈α∞of␈α
the␈α∞environment,␈α
but␈α∞as␈α∞we␈α
do␈α∞that␈α
we␈α∞␈↓↓swap␈↓␈α∞the␈α
current␈α∞contents␈α∞of␈α
the
␈↓ ↓H␈↓affected␈α
value␈α
cells␈α∞with␈α
the␈α
new␈α∞values.␈α
This␈α
establishes␈α∞the␈α
new␈α
values␈α∞in␈α
the␈α
value␈α∞cells␈α
while
␈↓ ↓H␈↓saving␈α⊃the␈α⊃prior␈α⊃bindings.␈α⊃We␈α⊃are␈α⊃now␈α⊂ready␈α⊃to␈α⊃evaluate␈α⊃the␈α⊃body␈α⊃of␈α⊃the␈α⊃application.␈α⊂When
␈↓ ↓H␈↓evaluation␈αis␈αcompleted␈αwe␈αswap␈α␈↓↓back␈↓,␈αusing␈αthe␈αfirst␈αblock␈αof␈αthe␈αsaved␈αenvironment␈α
chain;␈αthen
␈↓ ↓H␈↓we␈α
remove␈αthat␈α
first␈αblock␈α
from␈αthe␈α
chain.␈αSince␈α
we␈αare␈α
assuming␈αa␈α
simple␈αfunction␈α
call,␈α
that␈αold
␈↓ ↓H␈↓␈↓αdest␈↓␈αblock␈αis␈αno␈αlonger␈αaccessible␈αand␈αcan␈αbe␈αcollected␈↓π 183␈↓.␈α The␈αallocation␈αand␈αde-allocation␈α
process
␈↓ ↓H␈↓is␈αstack-like;␈α
we␈αwill␈αdevelop␈α
our␈αimplementation␈αusing␈α
a␈αstack␈αcalled␈α
the␈αSpecial␈α
Pushdown␈αstack.
␈↓ ↓H␈↓This␈αstack␈αwill␈αbe␈αreferenced␈αby␈αa␈αstack␈αpointer␈αcalled␈α␈↓
SP␈↓␈αor␈αcalled␈α␈↓
ENV␈↓␈αwhen␈αwe␈αwish␈αto␈αreinforce
␈↓ ↓H␈↓its relation to the more general environment structures.
␈↓ ↓H␈↓In the spirit of the evaluator of Section 4.6, we would evaluate ␈↓αλ[[x;y] ␈↓λx␈↓α][C;D]␈↓ as follows:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α
Allocate␈α
space␈α
for␈α
the␈α
parameters␈α
␈↓αx␈↓␈α
and␈α
␈↓αy␈↓.␈α
This␈α
space␈α
is␈α
reserved␈α
on␈α
the␈α
top␈α
of␈α
the␈α
␈↓
ENV␈↓␈αstack,␈α
and
␈↓ ↓H␈↓␈↓ ↓his referenced by a pointer named ␈↓
DEST␈↓.
␈↓ ↓H␈↓␈↓↓2.␈↓ Evaluate the actual parameters and send the results to the ␈↓αdest␈↓ block.
␈↓ ↓H␈↓␈↓↓3.␈↓␈αSwap␈α
the␈αcontents␈αof␈α
the␈αvalue␈α
cells␈αfor␈α␈↓αx␈↓␈α
and␈α␈↓αy␈↓␈αwith␈α
the␈αcontents␈α
of␈αthe␈α␈↓αdest␈↓␈α
block.␈αMove␈α␈↓
ENV␈↓␈α
to
␈↓ ↓H␈↓␈↓ ↓hpoint to the ␈↓αdest␈↓ block.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 182␈↓ This scheme will also work with multi-valued functions.
␈↓ ↓H␈↓␈↓π 183␈↓␈α
Since␈α
the␈α
␈↓αdest␈↓␈α
block␈α∞is␈α
no␈α
longer␈α
accessible,␈α
it␈α
was␈α∞unnecessary␈α
to␈α
␈↓↓swap␈↓␈α
back;␈α
we␈α∞could␈α
have
␈↓ ↓H␈↓simply␈α⊗␈↓↓restored␈↓␈α⊗the␈α⊗value␈α∃cells.␈α⊗The␈α⊗swap␈α⊗was␈α∃described␈α⊗in␈α⊗preparation␈α⊗for␈α⊗more␈α∃general
␈↓ ↓H␈↓implementations.
␈↓ ↓H␈↓␈↓↓5.19␈↓ ε<Stack Implementation of Shallow Binding 275␈↓
␈↓ ↓H␈↓␈↓↓4.␈↓ Evaluate ␈↓λx␈↓. Within ␈↓λx␈↓, ␈↓αlookup␈↓ will go to the value cells for all variable references.
␈↓ ↓H␈↓␈↓↓5.␈↓␈αRestore␈α
the␈αold␈αenvironment.␈α
Swap␈αthe␈α
contents␈αof␈αthe␈α
first␈αblock␈α
of␈α␈↓
ENV␈↓␈αwith␈α
the␈αcontents␈αof␈α
the
␈↓ ↓H␈↓␈↓ ↓happropriate value cells.
␈↓ ↓H␈↓␈↓↓6.␈↓ Set ␈↓
ENV␈↓ to point at the prior block.
␈↓ ↓H␈↓To␈α⊂reinforce␈α⊂these␈α⊂notions␈α⊂we␈α⊂supply␈α∂a␈α⊂more␈α⊂detailed␈α⊂implementation.␈α⊂ We␈α⊂will␈α⊂implement␈α∂our
␈↓ ↓H␈↓value␈α∀cells␈α∀as␈α∀elements␈α∀of␈α∪the␈α∀property␈α∀lists.␈α∀ The␈α∀property␈α∪name␈α∀will␈α∀be␈α∀␈↓αVALUE␈↓,␈α∀and␈α∪the
␈↓ ↓H␈↓corresponding␈αproperty␈αvalue␈αwill␈αbe␈αthe␈αvalue␈αcell.␈α
Assume␈α␈↓αx␈↓␈αand␈α␈↓αy␈↓␈αare␈αcurrently␈αbound␈αto␈α␈↓αA␈↓␈α
and
␈↓ ↓H␈↓␈↓αB␈↓ respectively; and assume we wish to evaluate:
␈↓ ↓H␈↓␈↓ ¬o␈↓αλ[[x;y] ␈↓λx␈↓α][C;D]␈↓.
␈↓ ↓H␈↓␈↓ ∧-We assume ␈↓
ENV␈↓ is in some well-defined state:
␈↓"␈↓ ↓H␈↓
part of atom for X part of atom for Y
␈↓"␈↓ ↓H␈↓
⊂αααααααπααα⊃ ⊂αααπαα ⊂αααααααπααα⊃ ⊂αααπαα
␈↓"␈↓ ↓H␈↓
ENV ~ VALUE ~ #αβ→~ A ~ #→... ~ VALUE ~ #αβ→~ B ~ #→...
␈↓"␈↓ ↓H␈↓
⊂αααα⊃ εααααααααααααλ %ααααααα∀ααα$ %ααα∀αα %ααααααα∀ααα$ %ααα∀αα
␈↓"␈↓ ↓H␈↓
~ #αβα→~*MARK* #ααβ→⊃
␈↓"␈↓ ↓H␈↓
%αααα$ εααααααααααααλ ↓
␈↓"␈↓ ↓H␈↓
~ last entry ~ ~
␈↓"␈↓ ↓H␈↓
εααααααααααααλ ~
␈↓"␈↓ ↓H␈↓
...
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
εααααααααααααλ←$
␈↓"␈↓ ↓H␈↓
~*MARK* #ααβ→⊃
␈↓"␈↓ ↓H␈↓
εααααααααααααλ ↓
␈↓"␈↓ ↓H␈↓
...
␈↓ ↓H␈↓In␈α∂this␈α⊂implementation,␈α∂the␈α∂stack␈α⊂is␈α∂organized␈α⊂in␈α∂blocks.␈α∂ The␈α⊂allocation␈α∂operation␈α⊂claims␈α∂space
␈↓ ↓H␈↓from␈α
the␈α
top␈α
of␈α
the␈α
stack␈α
and␈αputs␈α
a␈α
special␈α
mark␈α
in␈α
the␈α
top␈αof␈α
the␈α
␈↓
ENV␈↓␈α
stack␈α
to␈α
delimit␈α
the␈αblock␈α
of
␈↓ ↓H␈↓λ-rebindings;␈α∪that␈α∪marked␈α∪entry␈α∪will␈α∪also␈α∪contain␈α∪the␈α∪␈↓αdest␈↓␈α∪pointer.␈α∪ The␈α∀implementation␈α∪will
␈↓ ↓H␈↓indicate␈α∞the␈α∞new␈α∞block␈α∞by␈α∞pointing␈α∞to␈α∞it␈α∞by␈α∞␈↓
DEST␈↓.␈α∞ The␈α∞allocation␈α∞routine␈α∞is␈α∞also␈α∂responsible␈α∞for
␈↓ ↓H␈↓filling␈αthe␈αname-entries␈αof␈αthe␈α␈↓αdest␈↓␈αblock.␈αThose␈αentries␈αwill␈αbe␈αrepresented␈αas␈αpointers␈αto␈αthe␈αvalue
␈↓ ↓H␈↓cell entry on the property list of the atom.
␈↓ ↓H␈↓␈↓↓276 static structure␈↓ (5.19␈↓
␈↓"␈↓ ↓H␈↓
DEST ⊂ααααααα→ααααααααα→αααααααααααααα→⊃
␈↓"␈↓ ↓H␈↓
⊂αααα⊃↑ ⊂αααααααααααα⊃ ↓
␈↓"␈↓ ↓H␈↓
~ #αββ→~*MARK* #ααβ→⊃ ~
␈↓"␈↓ ↓H␈↓
%αααα$↑ εαααααααπααααλ ~ ~
␈↓"␈↓ ↓H␈↓
%←β←α# ~ ~←$ part of atom ↓ for X part of atom for Y
␈↓"␈↓ ↓H␈↓
εαααααααβααααλ ⊂αααααααπααα⊃ ⊂αααπαα ⊂αααααααπααα⊃ ⊂αααπαα
␈↓"␈↓ ↓H␈↓
ENV ~←to Y←#~ ~ ~ VALUE ~ #αβ→~ A ~ #→... ~ VALUE ~ #αβ→~ B ~ #→...
␈↓"␈↓ ↓H␈↓
⊂αααα⊃ εααααααα∀ααααλ %ααααααα∀ααα$ %ααα∀αα %ααααααα∀ααα$ %ααα∀αα
␈↓"␈↓ ↓H␈↓
~ #αβα→~*MARK* #ααβ→⊃
␈↓"␈↓ ↓H␈↓
%αααα$ εααααααααααααλ ↓
␈↓"␈↓ ↓H␈↓
~ last entry ~ ~
␈↓"␈↓ ↓H␈↓
εααααααααααααλ ~
␈↓"␈↓ ↓H␈↓
...
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
εααααααααααααλ←$
␈↓"␈↓ ↓H␈↓
~*MARK* #ααβ→⊃
␈↓"␈↓ ↓H␈↓
εααααααααααααλ ↓
␈↓"␈↓ ↓H␈↓
...
␈↓ ↓H␈↓The␈α
␈↓αsend␈↓␈α
operation␈α
will␈αfill␈α
the␈α
␈↓αdest␈↓␈α
entries␈αfor␈α
␈↓αx␈↓␈α
and␈α
␈↓αy␈↓.␈α
The␈α␈↓αnext␈↓␈α
operation␈α
will␈α
increment␈αthe␈α
␈↓αdest␈↓
␈↓ ↓H␈↓pointer␈αso␈αthat␈αafter␈αall␈αentries␈αhave␈αbeen␈αmade␈αto␈αthe␈α␈↓αdest␈↓␈αblock,␈αthe␈α␈↓αdest␈↓␈αpointer␈αwill␈αindicate␈αthe
␈↓ ↓H␈↓next block of saved bindings.
␈↓ ↓H␈↓With␈α␈↓αx␈↓␈αand␈α␈↓αy␈↓␈αbound␈αto␈α␈↓αC␈↓␈αand␈α␈↓αD␈↓␈αin␈αthe␈α␈↓αdest␈↓␈αblock,␈αwe␈αare␈αready␈αto␈αswap␈αthe␈αvalue␈αcells.␈α After␈αthe
␈↓ ↓H␈↓swap the picture is:
␈↓"␈↓ ↓H␈↓
ENV ⊂ααααααα→ααααααααα→αααααααααααααα→⊃
␈↓"␈↓ ↓H␈↓
⊂αααα⊃↑ ⊂αααααααααααα⊃ ↓
␈↓"␈↓ ↓H␈↓
~ #αββ→~*MARK* #ααβ→⊃ ~
␈↓"␈↓ ↓H␈↓
%αααα$↑ εαααααααπααααλ ~ ~
␈↓"␈↓ ↓H␈↓
%←β←α# ~ A ~ ~ part of atom ↓ for X part of atom for Y
␈↓"␈↓ ↓H␈↓
εαααααααβααααλ ↓ ⊂αααααααπααα⊃ ⊂αααπαα ⊂αααααααπααα⊃ ⊂αααπαα
␈↓"␈↓ ↓H␈↓
~←to Y←#~ B ~←$ ~ VALUE ~ #αβ→~ C ~ #→... ~ VALUE ~ #αβ→~ D ~ #→...
␈↓"␈↓ ↓H␈↓
εααααααα∀ααααλ %ααααααα∀ααα$ %ααα∀αα %ααααααα∀ααα$ %ααα∀αα
␈↓"␈↓ ↓H␈↓
~*MARK* #ααβ→⊃
␈↓"␈↓ ↓H␈↓
εααααααααααααλ ↓
␈↓"␈↓ ↓H␈↓
~ last entry ~ ~
␈↓"␈↓ ↓H␈↓
εααααααααααααλ ~
␈↓"␈↓ ↓H␈↓
...
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
εααααααααααααλ←$
␈↓"␈↓ ↓H␈↓
~*MARK* #ααβ→⊃
␈↓"␈↓ ↓H␈↓
εααααααααααααλ ↓
␈↓"␈↓ ↓H␈↓
...
␈↓ ↓H␈↓Now␈α
␈↓αx␈↓␈α
and␈α
␈↓αy␈↓␈α
have␈α
values␈α␈↓αC␈↓␈α
and␈α
␈↓αD␈↓␈α
respectively␈α
and␈α
the␈αprevious␈α
bindings␈α
are␈α
saved␈α
on␈α
the␈α␈↓
ENV␈↓
␈↓ ↓H␈↓stack.␈α
We␈α
may␈α
now␈α
begin␈α
the␈αevaluation␈α
of␈α
␈↓λx␈↓␈α
assured␈α
that␈α
we␈αwill␈α
get␈α
the␈α
expected␈α
values␈α
for␈α␈↓αx␈↓␈α
and
␈↓ ↓H␈↓␈↓αy␈↓.␈α We␈αhave␈αalso␈α
saved␈αsufficient␈αinformation␈αto␈αrestore␈α
the␈αprevious␈αvalues␈αafterwards.␈α
Since␈αwe
␈↓ ↓H␈↓are␈αassuming␈α
simple␈αfunction␈α
composition,␈αthe␈αunbind␈α
operation␈αcan␈α
simply␈α"pop"␈α
entries␈αoff␈αof␈α
the
␈↓ ↓H␈↓top of ␈↓
ENV␈↓ into the value cells rather than swap them with the value cells.
␈↓ ↓H␈↓␈↓↓5.19␈↓ ε<Stack Implementation of Shallow Binding 277␈↓
␈↓ ↓H␈↓The␈α⊂unbinder␈α⊃restores␈α⊂the␈α⊃first␈α⊂block␈α⊃of␈α⊂saved␈α⊂values␈α⊃using␈α⊂the␈α⊃pointers␈α⊂to␈α⊃the␈α⊂value␈α⊃cells␈α⊂as
␈↓ ↓H␈↓destinations␈α∩for␈α∩the␈α∩values␈↓π 184␈↓.␈α∩ This␈α∩stack␈α∩of␈α∩previous␈α∩values␈α∩is␈α∩also␈α∩visited␈α∩by␈α∪the␈α∩garbage
␈↓ ↓H␈↓collector;␈α∞it␈α∞may␈α
be␈α∞that␈α∞the␈α∞only␈α
copy␈α∞of␈α∞some␈α
value␈α∞is␈α∞accessible␈α∞only␈α
through␈α∞the␈α∞␈↓
ENV␈↓␈α∞stack.␈α
It
␈↓ ↓H␈↓would␈αbe␈αmost␈αunfortunate␈αif␈αthe␈αgarbage␈α
collector␈αneglected␈αto␈αmark␈αthat␈αentry␈αand␈αthe␈α
unbinding
␈↓ ↓H␈↓mechanism later tried to restore the value.
␈↓ ↓H␈↓This␈αimplementation␈αworks␈αquite␈αwell␈αfor␈αsimple␈αλ-binding␈αand␈αlookup.␈αChanging␈αenvironments␈αis
␈↓ ↓H␈↓a␈αbit␈αof␈α
work,␈αbut␈αthe␈αaccess␈α
to␈αthe␈αvalues␈α
of␈αvariables␈αis␈αrelatively␈α
rapid,␈αparticularly␈αif␈α
we␈αmake
␈↓ ↓H␈↓sure␈α⊂that␈α⊃the␈α⊂value␈α⊂cell␈α⊃is␈α⊂always␈α⊂stored␈α⊃at␈α⊂a␈α⊂known␈α⊃position␈α⊂relative␈α⊂to␈α⊃the␈α⊂beginning␈α⊃of␈α⊂the
␈↓ ↓H␈↓property␈α
list.␈α
In␈α
describing␈α
this␈α
implementation␈αwe␈α
have␈α
used␈α
more␈α
representation␈α
than␈αmight␈α
seem
␈↓ ↓H␈↓appropriate.␈α
In␈α∞particular␈α
the␈α
representation␈α∞of␈α
the␈α
value␈α∞cell␈α
as␈α
a␈α∞linked␈α
list␈α∞seems␈α
unnecessarily
␈↓ ↓H␈↓explicit. This was done to illuminate the pointer modifications involved in binding and unbinding.
␈↓ ↓H␈↓We␈α
would␈α
like␈αto␈α
implement␈α
functional␈αarguments␈α
in␈α
this␈α
shallow␈αbinder.␈α
Recall␈α
how␈αdeep␈α
binding
␈↓ ↓H␈↓coped.␈α⊃ When␈α⊃we␈α⊂recognized␈α⊃an␈α⊃instance␈α⊃of␈α⊂a␈α⊃functional␈α⊃argument␈α⊃we␈α⊂saved␈α⊃a␈α⊃pointer␈α⊃to␈α⊂the
␈↓ ↓H␈↓current␈α∞environment.␈α∞When␈α
we␈α∞␈↓↓applied␈↓␈α∞the␈α
functional␈α∞argument␈α∞we␈α
restored␈α∞the␈α∞symbol␈α∞table␈α
in
␈↓ ↓H␈↓such␈αa␈α
way␈αthat␈αglobal␈α
variables␈αwere␈α
accessed␈αin␈αthe␈α
saved␈αenvironment␈α
while␈αlocal␈αvariables␈α
were
␈↓ ↓H␈↓found␈α∂in␈α∂the␈α∞current␈α∂environment.␈α∂ We␈α∞must␈α∂try␈α∂to␈α∞do␈α∂the␈α∂same␈α∞with␈α∂the␈α∂shallow-binding.␈α∞The
␈↓ ↓H␈↓action␈α∞taken␈α∞when␈α∞a␈α∞functional␈α∞argument␈α∂is␈α∞recognized␈α∞is␈α∞quite␈α∞similar␈α∞to␈α∞our␈α∂previous␈α∞solution:
␈↓ ↓H␈↓when␈α∞␈↓αfunction␈↓␈α
is␈α∞seen,␈α∞save␈α
the␈α∞current␈α
␈↓
ENV␈↓␈α∞pointer.␈α∞ This␈α
setting␈α∞of␈α
␈↓
ENV␈↓␈α∞establishes␈α∞the␈α
binding
␈↓ ↓H␈↓environment,␈α↔and␈α⊗is␈α↔therefore␈α⊗callled␈α↔the␈α⊗␈↓↓binding␈α↔context␈α⊗pointer␈↓.␈α↔ The␈α↔action␈α⊗therefore,
␈↓ ↓H␈↓manufactures a triple ␈↓α(FUNARG ␈↓<function> <binding context pointer>␈↓α)␈↓.
␈↓ ↓H␈↓However,␈α⊃the␈α∩action␈α⊃required␈α⊃when␈α∩we␈α⊃wish␈α⊃to␈α∩apply␈α⊃the␈α⊃functional␈α∩argument␈α⊃is␈α∩much␈α⊃more
␈↓ ↓H␈↓complicated.␈α
In␈αthe␈α
deep␈α
binding␈αimplementation␈α
we␈α
just␈αset␈α
up␈αa␈α
new␈α
access␈αchain␈α
such␈α
that␈αthe
␈↓ ↓H␈↓local␈α∂table␈α∞referred␈α∂to␈α∞binding␈α∂environment␈α∂saved␈α∞by␈α∂the␈α∞␈↓αFUNARG␈↓␈α∂construction.␈α∂ The␈α∞problem
␈↓ ↓H␈↓with␈α⊂the␈α⊂shallow-binder␈α⊂is␈α⊂that␈α⊂␈↓
ENV␈↓␈α∂only␈α⊂reflects␈α⊂the␈α⊂␈↓↓incremental␈↓␈α⊂changes␈α⊂in␈α⊂the␈α∂environments
␈↓ ↓H␈↓during␈α∞the␈α∞computation.␈α∞To␈α
retrieve␈α∞the␈α∞environment␈α∞current␈α
when␈α∞the␈α∞functional␈α∞argument␈α
was
␈↓ ↓H␈↓bound,␈α⊂we␈α⊂must␈α⊂unwind␈α⊂␈↓
ENV␈↓␈α⊂back␈α⊂to␈α⊂the␈α⊂binding␈α⊂environment;␈α⊂we␈α⊂must␈α⊂also␈α⊂save␈α⊂the␈α⊂current
␈↓ ↓H␈↓activation␈α
environment␈α∞so␈α
that␈α∞we␈α
may␈α∞return␈α
to␈α
␈↓↓it␈↓␈α∞when␈α
finished␈α∞with␈α
the␈α∞functional␈α
argument.
␈↓ ↓H␈↓Since␈α∂we␈α∂are␈α∂dealing␈α∂with␈α∂a␈α∂functional␈α∞argument,␈α∂rather␈α∂than␈α∂a␈α∂functional␈α∂value,␈α∂we␈α∂can␈α∞easily
␈↓ ↓H␈↓locate␈α
the␈α
binding␈α
context␈α
pointer.␈α∞The␈α
pointer␈α
is␈α
␈↓↓below␈↓␈α
the␈α∞current␈α
␈↓
ENV␈↓␈α
in␈α
the␈α
stack.␈α∞We␈α
search
␈↓ ↓H␈↓down␈α∞the␈α
stack␈α∞for␈α
that␈α∞saved␈α
pointer,␈α∞swapping␈α∞back␈α
the␈α∞saved␈α
value␈α∞cells.␈α
When␈α∞we␈α∞reach␈α
the
␈↓ ↓H␈↓binding␈α∞context␈α∞pointer␈α∂we␈α∞stop.␈α∞At␈α∞that␈α∂time␈α∞the␈α∞value␈α∞cells␈α∂have␈α∞been␈α∞restored␈α∞to␈α∂the␈α∞binding
␈↓ ↓H␈↓environment␈α∂and␈α∞the␈α∂segment␈α∂of␈α∞the␈α∂stack␈α∞between␈α∂the␈α∂activation␈α∞environment␈α∂and␈α∂the␈α∞binding
␈↓ ↓H␈↓environment␈α
accurately␈α
reflects␈α
the␈α
bindings␈αwhich␈α
were␈α
made␈α
between␈α
binding␈α
and␈αactivation;␈α
that
␈↓ ↓H␈↓is,␈α∩that␈α⊃segment␈α∩of␈α⊃the␈α∩stack␈α⊃is␈α∩deep␈α⊃bound.␈α∩ That␈α⊃stack␈α∩segment␈α⊃must␈α∩be␈α⊃saved␈α∩so␈α∩that␈α⊃the
␈↓ ↓H␈↓activation␈α
environment␈α
can␈α
be␈α
restored,␈α
thus␈α
␈↓
ENV␈↓␈α
is␈α
not␈α
restored␈α
to␈α
the␈α
binding␈α
context,␈αbut␈α
remains
␈↓ ↓H␈↓where it was.
␈↓ ↓H␈↓This process is complex enough to warrant an example.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 184␈↓␈αAn␈αalternative␈αimplementation␈αwould␈αonly␈αstore␈αthe␈αsaved␈αvalues,␈αwithout␈αexplicitly␈αsaving␈α
the
␈↓ ↓H␈↓locations,␈α∞and␈α∞without␈α∞marking␈α
the␈α∞stack.␈α∞In␈α∞this␈α
implementation␈α∞the␈α∞unbinder␈α∞would␈α∞require␈α
an
␈↓ ↓H␈↓argument describing which variables needed restoring.
␈↓ ↓H␈↓␈↓↓278 static structure␈↓ (5.19␈↓
␈↓ ↓H␈↓␈↓ ∧∀␈↓↓An example of shallow binding and ␈↓αFUNARG␈↓↓␈↓α
␈↓ ↓H␈↓␈↓↓I␈↓ Assume that ␈↓αx␈↓ initially has value ␈↓α1␈↓ and the ␈↓
SP␈↓ pointer is at location ␈↓
SP1␈↓,
␈↓ ↓H␈↓␈↓↓II␈↓ then assume that a λ-binding rebinds ␈↓αx␈↓ to ␈↓α2␈↓;
␈↓ ↓H␈↓␈↓↓III␈↓ in this new context, assume a functional argument, ␈↓αg␈↓, is to be bound to a function-variable ␈↓αf␈↓.
␈↓ ↓H␈↓␈↓↓IV-V␈↓␈αAs␈αthe␈αcomputation␈αcontinues␈α␈↓αx␈↓␈αis␈αrebound␈αfirst␈αto␈α␈↓α3␈↓␈αand␈αwithin␈α␈↓↓that␈↓␈αcontext␈αrebound␈αagain
␈↓ ↓H␈↓␈↓ α_to ␈↓α4␈↓.
␈↓ ↓H␈↓␈↓↓VI␈↓␈αFinally␈α␈↓αf␈↓␈αis␈αapplied;␈αthis␈αwill␈αresurrect␈α␈↓αg␈↓␈↓π 185␈↓␈αrequiring␈αa␈αrestoration␈αof␈αthe␈αenvironment␈αcurrent
␈↓ ↓H␈↓␈↓ α_at step ␈↓↓III␈↓.
␈↓ ↓H␈↓Steps ␈↓↓I␈↓ through ␈↓↓V␈↓ would lead to the following sequence.
␈↓"␈↓ ↓H␈↓
F: (FUNARG G #)
␈↓"␈↓ ↓H␈↓
X: 1 X: 2 X: 2 ↓
␈↓"␈↓ ↓H␈↓
εααα∀αααλ εαααβαααλ ⊂ααα←ααα$
␈↓"␈↓ ↓H␈↓
SP1 αα→~*MARK* ~ =II=> SP2 αα→~ X ~ 1 ~ =III=> ↓
␈↓"␈↓ ↓H␈↓
εαααπαααλ εααα∀αααλ SP2 ∀α→~ X ~ 1 ~
␈↓"␈↓ ↓H␈↓
... ~*MARK* ~ ...
␈↓"␈↓ ↓H␈↓
εαααπαααλ
␈↓"␈↓ ↓H␈↓
...
␈↓"␈↓ ↓H␈↓
SP1 αα→~ ... ~
␈↓"␈↓ ↓H␈↓
X: 3 X: 4
␈↓"␈↓ ↓H␈↓
=IV=> SP3 αα→~ X ~ 2 ~ =V=> SP4 εαααβαααλ
␈↓"␈↓ ↓H␈↓
εαααβαααλ %α→~ X ~ 3 ~
␈↓"␈↓ ↓H␈↓
. . . εαααβαααλ
␈↓"␈↓ ↓H␈↓
SP2 αα→~ X ~ 1 ~ . . .
␈↓"␈↓ ↓H␈↓
εαααβαααλ
␈↓"␈↓ ↓H␈↓
...
␈↓ ↓H␈↓Now␈αto␈αapply␈α
the␈αfunctional␈αargument:␈α␈↓α(FUNARG␈α
G␈αSP2)␈↓.␈α This␈α
is␈αaccomplished␈αby␈αtracing␈α
down
␈↓ ↓H␈↓the␈α∪␈↓
SP␈↓␈α∩stack␈α∪with␈α∩a␈α∪pointer␈α∩␈↓
SP*␈↓,␈α∪moving␈α∩from␈α∪␈↓
SP4␈↓␈α∩--the current stack pointer--␈α∪down␈α∪to␈α∩␈↓
SP2␈↓
␈↓ ↓H␈↓--the ␈↓αFUNARG␈↓ pointer--,␈α∩reversing␈α⊃all␈α∩the␈α⊃intervening␈α∩bindings␈α⊃on␈α∩SP␈α⊃and␈α∩putting␈α∩the␈α⊃saved
␈↓ ↓H␈↓values␈α⊃back␈α⊂into␈α⊃the␈α⊃value cell.␈α⊂ The␈α⊃pattern␈α⊃of␈α⊂these␈α⊃reversals␈α⊂must␈α⊃be␈α⊃saved;␈α⊂we␈α⊃do␈α⊃this␈α⊂by
␈↓ ↓H␈↓swapping the values back into the stack segment between ␈↓
SP4␈↓ and ␈↓
SP2␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 185␈↓ From the value cell of ␈↓αf␈↓ as ␈↓α(FUNARG G SP2)␈↓.
␈↓ ↓H␈↓␈↓↓5.19␈↓ ε<Stack Implementation of Shallow Binding 279␈↓
␈↓ ↓H␈↓Thus, steps ␈↓↓VII␈↓ and ␈↓↓VIII␈↓:
␈↓"␈↓ ↓H␈↓
X:3 X: 2
␈↓"␈↓ ↓H␈↓
...
␈↓"␈↓ ↓H␈↓
... ...
␈↓"␈↓ ↓H␈↓
SP4 α→~ X ~ 4 ~ SP4 α→~ X ~ 4 ~
␈↓"␈↓ ↓H␈↓
εαααβαααλ εαααβαααλ
␈↓"␈↓ ↓H␈↓
... ...
␈↓"␈↓ ↓H␈↓
=VII=> SP3 α→~ X ~ 2 ~ ←αα SP* =VIII=> SP3 α→~ X ~ 3 ~
␈↓"␈↓ ↓H␈↓
... ...
␈↓"␈↓ ↓H␈↓
εαααβαααλ εαααβαααλ
␈↓"␈↓ ↓H␈↓
SP2 α→~ X ~ 1 ~ SP2 α→~ X ~ 1 ~ ←αα SP*
␈↓"␈↓ ↓H␈↓
... . . .
␈↓ ↓H␈↓Now␈α
we␈α
are␈α
in␈α
a␈αposition␈α
to␈α
evaluate␈α
the␈α
call␈αon␈α
␈↓αg␈↓;␈α
when␈α
we␈α
are␈αfinished␈α
with␈α
␈↓αg␈↓␈α
we␈α
will␈α
use␈αthe
␈↓ ↓H␈↓unbinding␈α⊂mechanism␈α⊂to␈α⊂reinstate␈α⊂the␈α⊂world␈α⊂as␈α⊂it␈α⊂existed␈α⊂at␈α⊂␈↓
SP4␈↓.␈α⊂This␈α⊂process␈α⊂will␈α⊂restore␈α∂the
␈↓ ↓H␈↓value cells using the areas of the stack between ␈↓
SP2␈↓ and ␈↓
SP4␈↓.
␈↓ ↓H␈↓Functional␈αarguments␈αare␈αmore␈αdifficult␈α
since␈αthere␈αis␈αonly␈αone␈α
symbol␈αtable,␈αnot␈αthe␈αstack␈αof␈α
tables
␈↓ ↓H␈↓implicit␈αin␈αthe␈αprevious␈αincarnation.␈αTrue,␈αthe␈αinformation␈αnecessary␈αto␈αrecover␈αan␈αenvironment␈αis
␈↓ ↓H␈↓present in ␈↓
SP␈↓, but it is expensive to retrieve it.
␈↓ ↓H␈↓Though␈αthe␈αstack␈αimplementation␈α
of␈αshallow␈αbinding␈α␈↓↓will␈↓␈α
perform␈αfor␈αfunctional␈αarguments,␈αit␈α
will
␈↓ ↓H␈↓involve␈α
even␈αmore␈α
complexity␈α
if␈αwe␈α
wish␈αto␈α
handle␈α
functional␈αvalues.␈α
The␈α
difficulty␈αis␈α
the␈αsame␈α
as
␈↓ ↓H␈↓that␈α⊂for␈α∂the␈α⊂stack␈α∂implementation␈α⊂of␈α∂deep␈α⊂binding:␈α∂the␈α⊂␈↓αFUNARG␈↓␈α∂will␈α⊂point␈α∂"up"␈α⊂the␈α⊂␈↓
SP␈↓␈α∂stack
␈↓ ↓H␈↓rather␈αthan␈α"down".␈α A␈αstraightforward␈αapplication␈αof␈αthe␈αtechnique␈αused␈αfor␈αfunctional␈αarguments
␈↓ ↓H␈↓will␈α∞not␈α∞work.␈α∞At␈α∂the␈α∞time␈α∞we␈α∞wished␈α∂to␈α∞apply␈α∞the␈α∞functional␈α∂value␈α∞its␈α∞saved␈α∞␈↓
SP␈↓-pointer␈α∂will␈α∞be
␈↓ ↓H␈↓pointing␈αinto␈αa␈αsection␈α
of␈αthe␈α␈↓
SP␈↓␈αstack␈αwhich␈α
no␈αlonger␈αreflects␈αthe␈α
proper␈αstate.␈αFor␈αwhen␈αwe␈α
leave
␈↓ ↓H␈↓the␈αenvironment␈αwhich␈αcreated␈αthe␈αfunctional␈αvalue␈αthe␈αcurrent␈αunbinding␈αmechanism␈αwill␈αcut␈αthe
␈↓ ↓H␈↓stack back to the point which existed when we entered that environment.
␈↓ ↓H␈↓The␈α
generalization␈αof␈α
this␈αshallow␈α
binding␈αscheme␈α
to␈αfunctional␈α
values␈αis␈α
possible.␈αThere␈α
are␈αtwo
␈↓ ↓H␈↓problems␈α
to␈α
be␈α
solved.␈α
First,␈αthe␈α
storage␈α
for␈α
␈↓
ENV␈↓␈α
and␈α
␈↓
DEST␈↓␈αmust␈α
be␈α
generalized␈α
to␈α
be␈αtree-like␈α
rather
␈↓ ↓H␈↓than␈αstack-like.␈αThis␈αgeneralization␈αis␈αnot␈αsimply␈αa␈αproblem␈αof␈αshallow␈αbinding.␈α The␈αdeep␈α
binding
␈↓ ↓H␈↓scheme␈α
builds␈α
a␈α
tree␈α
isomorphic␈α
to␈α
the␈α∞shallow␈α
tree;␈α
only␈α
the␈α
information␈α
saved␈α
in␈α∞the␈α
respective
␈↓ ↓H␈↓trees␈α∩differs.␈α∩ The␈α∩problem␈α∩which␈α∩the␈α∩shallow␈α∩binder␈α∩must␈α∩solve␈α∩is␈α∩how␈α∩to␈α∩rebind␈α∩from␈α⊃the
␈↓ ↓H␈↓activation␈αenvironment␈αto␈αthe␈αbinding␈αenvironment.␈α The␈αfunctional␈αargument␈αcase␈αwas␈αsimplified
␈↓ ↓H␈↓since␈α⊂the␈α⊂binding␈α⊂environment␈α⊃was␈α⊂on␈α⊂the␈α⊂same␈α⊂branch␈α⊃of␈α⊂the␈α⊂environment␈α⊂tree.␈α⊂In␈α⊃the␈α⊂more
␈↓ ↓H␈↓general␈α∂case␈α⊂the␈α∂binding␈α⊂environment␈α∂will␈α⊂be␈α∂on␈α∂a␈α⊂different␈α∂branch.␈α⊂ We␈α∂will␈α⊂investigate␈α∂some
␈↓ ↓H␈↓solutions to this problem in the next section.
␈↓ ↓H␈↓␈↓↓280 static structure␈↓ &5.20␈↓
␈↓ ↓H␈↓␈↓ ∧8␈↓↓5.20 Strategies for LISP Implementation␈↓
␈↓ ↓H␈↓The␈α⊂discussion␈α⊂of␈α⊂the␈α⊂last␈α∂three␈α⊂sections␈α⊂should␈α⊂be␈α⊂related␈α∂to␈α⊂the␈α⊂earlier␈α⊂discussion␈α⊂of␈α∂binding
␈↓ ↓H␈↓strategies,␈αWeizenbaum␈α
environments,␈αfunctional␈α
arguments␈αand␈α
the␈αnon-recursive␈αevaluators.␈α
Our
␈↓ ↓H␈↓mapping␈α
of␈αthe␈α
binding␈α
implementations␈α(shallow␈α
or␈αdeep)␈α
onto␈α
a␈αstack␈α
is␈αsufficient␈α
for␈α
the␈αgreat
␈↓ ↓H␈↓majority␈α⊂of␈α⊂LISP␈α⊂programs.␈α⊂However␈α⊂as␈α⊂the␈α∂LISP␈α⊂community␈α⊂explores␈α⊂new␈α⊂ways␈α⊂of␈α⊂using␈α∂the
␈↓ ↓H␈↓language,␈α∂they␈α∂have␈α∂begun␈α∂to␈α∞expect␈α∂that␈α∂the␈α∂full␈α∂power␈α∞of␈α∂functional␈α∂values␈α∂be␈α∂available;␈α∞and
␈↓ ↓H␈↓have␈α
proposed␈αextensions␈α
in␈αthe␈α
LISP␈αcontrol␈α
structure␈αto␈α
allow␈αeven␈α
non-recursive␈α
control.␈αSince
␈↓ ↓H␈↓these␈αtopics␈αare␈αof␈αcurrent␈αresearch␈αinterest␈αit␈αis␈αnot␈αclear␈αhow␈αlasting␈αtheir␈αimpact␈αwill␈αbe.␈αWe␈αwill
␈↓ ↓H␈↓sketch␈α∂a␈α∂few␈α⊂of␈α∂the␈α∂ideas␈α⊂involved␈α∂and␈α∂indicate␈α⊂how␈α∂the␈α∂techniques␈α⊂we␈α∂have␈α∂discussed␈α⊂in␈α∂this
␈↓ ↓H␈↓chapter can be applied.
␈↓ ↓H␈↓In␈α∞the␈α∞implementation␈α∞of␈α∞␈↓αeval␈↓␈α∞of␈α∞Section 3.5␈α∞we␈α∞represented␈α∞symbol␈α∞tables␈α∞as␈α∞list-structure.␈α
Later,
␈↓ ↓H␈↓when␈α∀we␈α∀introduced␈α∀the␈α∀␈↓αfunction␈↓␈α∀construct,␈α∀this␈α∀generality␈α∀became␈α∀necessary.␈α∀ As␈α∀long␈α∀as␈α∪a
␈↓ ↓H␈↓␈↓αFUNARG␈↓␈α∂construct␈α∂accessed␈α∂a␈α∂table,␈α∂then␈α∂that␈α∂table␈α∂was␈α∂retained.␈α∂However␈α∂symbol␈α∂tables␈α∂were
␈↓ ↓H␈↓then␈α∪a␈α∩garbage␈α∪collectible␈α∩commodity.␈α∪Essentially␈α∪we␈α∩had␈α∪removed␈α∩the␈α∪stack-like␈α∪behavior␈α∩of
␈↓ ↓H␈↓symbol-table␈α
accesses␈α
which␈α
occurs␈α
most␈α
of␈α
the␈αtime␈α
and␈α
replaced␈α
it␈α
with␈α
a␈α
general␈α
scheme␈αwhich
␈↓ ↓H␈↓works for all cases but incurs a significant overhead in even the most simple of function calls.
␈↓ ↓H␈↓We␈αwould␈αlike␈αan␈αintermediate␈αsolution:␈αone␈αwhich␈αworks␈αfor␈αall␈αcases␈αand␈αminimizes␈αoverhead␈αin
␈↓ ↓H␈↓the␈α⊃typical␈α⊃call.␈α⊂Such␈α⊃a␈α⊃scheme␈α⊃can␈α⊂indeed␈α⊃be␈α⊃implemented.␈α⊂ Recall␈α⊃our␈α⊃discussion␈α⊃of␈α⊂garbage
␈↓ ↓H␈↓collection␈α⊃in␈α⊃Section 5.14.␈α⊃There␈α⊃we␈α⊃said␈α⊃that␈α⊃a␈α⊃garbage␈α⊃collector␈α⊃was␈α⊃used␈α⊃in␈α⊃LISP␈α⊃since␈α⊃the
␈↓ ↓H␈↓interrelationships␈α⊗which␈α⊗we␈α⊗generated␈α⊗in␈α⊗the␈α⊗data␈α⊗structure␈α⊗manipulations␈α⊗were␈α∃sufficiently
␈↓ ↓H␈↓intertwined␈α⊃that␈α⊃it␈α∩was␈α⊃not␈α⊃possible␈α∩to␈α⊃use␈α⊃less␈α⊃sophisticated␈α∩methods␈α⊃to␈α⊃determine␈α∩whether␈α⊃a
␈↓ ↓H␈↓structure was still active.
␈↓ ↓H␈↓Symbol␈α∩tables␈α∩␈↓↓are␈↓␈α∪data␈α∩structures;␈α∩the␈α∩discussion␈α∪of␈α∩Weizenbaum␈α∩environments␈α∪in␈α∩Section 3.8
␈↓ ↓H␈↓should␈αhave␈αconvinced␈αyou␈αof␈αthat.␈α They␈αare␈αchained␈αtogether␈αin␈αa␈αmanner␈αreminiscent␈αof␈αthat␈αof
␈↓ ↓H␈↓our␈α⊗implementation␈α⊗of␈α⊗S-exprs;␈α⊗indeed␈α⊗as␈α∃we␈α⊗have␈α⊗just␈α⊗mentioned␈α⊗LISP's␈α⊗attitude␈α∃toward
␈↓ ↓H␈↓management␈αof␈αsuch␈α
tables␈αwas␈αto␈αgarbage␈α
collect␈αthem.␈αHowever␈αthe␈α
␈↓↓behavior␈↓␈αof␈αtables␈αduring␈α
the
␈↓ ↓H␈↓execution␈αof␈αa␈αprogram␈αis␈αmuch␈αless␈αcomplex␈αthan␈αthat␈αof␈αarbitrary␈αlist␈αstructure.␈αAs␈αwe␈αhave␈αjust
␈↓ ↓H␈↓seen,␈α∩the␈α∪behavior␈α∩is␈α∩predictable␈α∪except␈α∩for␈α∩procedure-valued␈α∪variables.␈α∩ A␈α∩solution␈α∪giving␈α∩a
␈↓ ↓H␈↓reasonable␈α∪implementation␈α∀based␈α∪on␈α∀the␈α∪alternative␈α∪storage␈α∀management␈α∪scheme␈α∀of␈α∪reference
␈↓ ↓H␈↓counters,␈α∂which␈α∂we␈α∂described␈α∂on␈α∂page 266,␈α∂is␈α∂described␈α∂in␈α∂[Bob 73a].␈α∂ Several␈α∂other␈α∞generalized
␈↓ ↓H␈↓control␈α∂schemes␈α∂have␈α∞been␈α∂proposed;␈α∂for␈α∂example␈α∞[Con 73],␈α∂[Gre 74],␈α∂[Mon 75],␈α∂and␈α∞[Wegb 75].
␈↓ ↓H␈↓The␈αintent␈αof␈α
all␈αthese␈αschemes␈α
is␈αthat␈αminimal␈αoverhead␈α
be␈αexperienced␈αif␈α
a␈αprogram␈αdoes␈αnot␈α
use
␈↓ ↓H␈↓the␈α∞more␈α
exotic␈α∞features:␈α
a␈α∞stack-like␈α
device␈α∞results.␈α
A␈α∞larger␈α
toll␈α∞is␈α
paid␈α∞for␈α
use␈α∞of␈α∞more␈α
general
␈↓ ↓H␈↓control regimes.
␈↓ ↓H␈↓It␈α␈↓↓is␈↓␈αpossible␈αto␈αconsider␈αcombining␈αthe␈αuse␈αof␈αthe␈αvalue␈αcell␈αwith␈αeither␈αshallow␈αor␈αdeep␈αstrategies.
␈↓ ↓H␈↓We␈αhave␈α␈↓↓both␈↓␈αa␈αvalue␈αcell␈αand␈αeither␈αname-value␈αtrees␈αor␈αshallow␈αbound␈αp-lists.␈αWe␈αwill␈αtry␈αto␈αuse
␈↓ ↓H␈↓the␈α∞value cell␈α∂as␈α∞much␈α∞as␈α∂possible.␈α∞ We␈α∞associate␈α∂an␈α∞extra␈α∞piece␈α∂of␈α∞information␈α∞with␈α∂each␈α∞value
␈↓ ↓H␈↓attached␈α
to␈α∞any␈α
value cell,␈α∞telling␈α
the␈α∞binding␈α
time␈α∞of␈α
that␈α∞variable.␈α
We␈α∞have␈α
a␈α∞global␈α
indicator
␈↓ ↓H␈↓telling␈αthe␈αcurrent␈αcontext␈αwhich␈αwe␈αare␈αusing:␈αE␈↓βcurrent␈↓,␈αsay.␈αWhen␈αwe␈αwant␈αthe␈αvalue␈αof␈αa␈αvariable,
␈↓ ↓H␈↓␈↓↓5.20␈↓ π⊂Strategies for LISP Implementation 281␈↓
␈↓ ↓H␈↓we␈α
first␈αgo␈α
to␈α
the␈αaugmented␈α
value cell;␈α
if␈αthe␈α
binding␈α
time␈αindication␈α
is␈α
that␈αof␈α
E␈↓βcurrent␈↓,␈α
then␈αthe
␈↓ ↓H␈↓value␈αis␈αcorrect␈αand␈αwe␈αtake␈αit.␈α If␈αthe␈αindicators␈αdisagree,␈αwe␈αuse␈αthe␈αfull␈α␈↓αlookup␈↓␈αstrategy;␈αwhen␈αwe
␈↓ ↓H␈↓find␈αthe␈αvariable␈αwe␈α
update␈αthe␈αvalue cell␈αand␈αchange␈α
the␈αbinding␈αtime␈αindicator␈αto␈α
E␈↓βcurrent␈↓.␈αThis
␈↓ ↓H␈↓way␈αwe␈αonly␈αsearch␈αthe␈αstacks␈αfor␈αthe␈αfirst␈α
access␈αto␈αa␈αvariable;␈αafter␈αthat␈αwe␈αcan␈αjustifiably␈αuse␈α
the
␈↓ ↓H␈↓value␈α↔cell␈α↔until␈α⊗we␈α↔change␈α↔context␈α⊗again.␈α↔This␈α↔scheme,␈α⊗called␈α↔␈↓↓cache value cells␈↓,␈α↔has␈α⊗been
␈↓ ↓H␈↓implemented in [Mud 75].
␈↓ ↓H␈↓Finally,␈α⊂we␈α⊂describe␈α⊂a␈α⊂full␈α⊃shallow␈α⊂binding␈α⊂implementation␈α⊂of␈α⊂functional␈α⊂values␈α⊃([Gre 74]).␈α⊂We
␈↓ ↓H␈↓identified␈αthe␈αcritical␈αproblem␈αas␈αthat␈α
of␈αdiscovering␈αthe␈αpath␈αbetween␈αthe␈α
activation␈αenvironment
␈↓ ↓H␈↓and␈αthe␈αbinding␈αenvironment.␈α Let␈αus␈αcall␈αthe␈αtwo␈αnodes␈αE␈↓βact␈↓␈αand␈αE␈↓βbind␈↓.␈αWith␈αany␈αnode␈αin␈αthe␈αtree
␈↓ ↓H␈↓is␈α
associated␈α
a␈α
flag␈α
named␈α
␈↓αactive␈↓;␈α
only␈α
nodes␈α
on␈α
the␈α
currently␈α
active␈α
branch␈α
are␈α
marked␈α∞␈↓αactive␈↓.␈α
It
␈↓ ↓H␈↓will␈α⊂be␈α⊃the␈α⊂responsibility␈α⊃of␈α⊂the␈α⊂binding␈α⊃and␈α⊂unbinding␈α⊃routines␈α⊂to␈α⊂maintain␈α⊃this␈α⊂flag.␈α⊃In␈α⊂the
␈↓ ↓H␈↓current␈αsituation,␈αE␈↓βact␈↓␈αis␈αon␈αthe␈αactive␈αbranch␈αand␈αE␈↓βbind␈↓␈αis␈αnot.␈αWe␈αgo␈αto␈αthe␈αnode␈αE␈↓βbind␈↓␈αand␈αsearch
␈↓ ↓H␈↓back␈αdown␈αits␈αbranch,␈αlooking␈αfor␈αa␈αnode␈αmarked␈α␈↓αactive␈↓.␈αCall␈αthis␈αnode␈αE␈↓βinter␈↓.␈αE␈↓βinter␈↓␈αrepresents␈αthe
␈↓ ↓H␈↓intersection of the active branch with the branch tipped in E␈↓βbind␈↓.
␈↓"␈↓ ↓H␈↓∂ ␈↓E␈↓βact␈↓∂ ␈↓E␈↓βbind␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ ␈↓∞G␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ ␈↓∞G␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ ␈↓∞G␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞HG␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓E␈↓βinter␈↓∂
␈↓"␈↓ ↓H␈↓∂ ↓
␈↓"␈↓ ↓H␈↓∂ . . .
␈↓ ↓H␈↓We␈α
now␈αgo␈α
E␈↓βact␈↓␈αand␈α
unbind␈αdown␈α
to␈αE␈↓βinter␈↓,␈α
swapping␈α
the␈αvalue␈α
cells␈αas␈α
we␈αgo.␈α
At␈αE␈↓βinter␈↓␈α
we␈αbind␈α
up
␈↓ ↓H␈↓to␈α
E␈↓βbind␈↓,␈αstill␈α
swapping␈αvalue␈α
cells.␈α
When␈αwe␈α
reach␈αE␈↓βbind␈↓␈α
the␈α
binding␈αenvironment␈α
has␈αbeen␈α
restored,
␈↓ ↓H␈↓and␈α∞the␈α∞path␈α∂from␈α∞E␈↓βbind␈↓␈α∞through␈α∂E␈↓βinter␈↓␈α∞to␈α∞E␈↓βact␈↓␈α∂contains␈α∞the␈α∞necessary␈α∂information␈α∞to␈α∞allow␈α∂us␈α∞to
␈↓ ↓H␈↓rebind to E␈↓βact␈↓ if desired.
␈↓ ↓H␈↓The␈α∞winding␈α
and␈α∞unwinding␈α
of␈α∞value␈α
cells␈α∞is␈α∞a␈α
time␈α∞consuming␈α
process,␈α∞much␈α
more␈α∞so␈α∞than␈α
the
␈↓ ↓H␈↓context␈αswap␈αused␈αin␈αa␈αdeep␈αbinding␈αscheme.␈α One␈αobjection␈αto␈αthis␈αimplementation␈αof␈αthe␈αshallow
␈↓ ↓H␈↓scheme␈αis␈α
that␈αit␈αoptimized␈α
for␈αthe␈α
case␈αthat␈αmany␈α
of␈αthe␈α
references␈αin␈αthe␈α
new␈αenvironment␈αwill␈α
be
␈↓ ↓H␈↓to␈α
free␈αvariables:␈α
those␈αvariables␈α
which␈αare␈α
non-local,␈α
but␈αare␈α
not␈αglobally␈α
bound.␈αIf␈α
a␈α
variable␈αis
␈↓ ↓H␈↓local␈α
or␈α
global,␈α
its␈αaccess␈α
is␈α
trivial.␈α
If␈αthere␈α
are␈α
no␈α
free␈α
references␈αin␈α
the␈α
new␈α
environment,␈αthen␈α
this
␈↓ ↓H␈↓shallow␈α∩swap␈α⊃is␈α∩not␈α⊃needed.␈α∩Alternative␈α⊃schemes␈α∩exist␈α⊃which␈α∩allow␈α⊃the␈α∩fast␈α⊃access␈α∩of␈α⊃shallow
␈↓ ↓H␈↓binding and allow the fast context swap of deep binding.
␈↓ ↓H␈↓␈↓ ¬s␈↓↓5.21 Epilogue␈↓
␈↓ ↓H␈↓␈↓ βB␈↓↓Subtitled: But my Fortran program doesn't do all this crap!␈↓
␈↓ ↓H␈↓␈↓↓282 static structure␈↓ (5.21␈↓
␈↓ ↓H␈↓It␈αis␈αquite␈α
true␈αthat␈αa␈α
running␈αFortran,␈αPL/1,␈α
or␈αAlgol␈αprogram␈α
is␈αfar␈αless␈α
complicated␈αin␈αits␈α
symbol
␈↓ ↓H␈↓accessing␈α∂mechanisms.␈α∂ In␈α∂Fortran␈α∂there␈α∂is␈α∂a␈α∂simple␈α∂relationship␈α∂between␈α∂variables␈α∂and␈α∞memory
␈↓ ↓H␈↓locations␈α⊂which␈α⊂will␈α⊂contain␈α∂their␈α⊂values;␈α⊂a␈α⊂Fortran␈α⊂evaluator␈α∂can␈α⊂assign␈α⊂fixed␈α⊂locations␈α⊂to␈α∂the
␈↓ ↓H␈↓variables␈αin␈αa␈αprogram.␈α In␈αAlgol,␈αthere␈αis␈αa␈αsimple␈αrelationship␈αbetween␈αvariables␈αand␈αpositions␈αin
␈↓ ↓H␈↓the␈αrun-time␈αstack;␈αan␈αAlgol␈αevaluator␈αcannot␈αassign␈αfixed␈αlocations,␈αbut␈αit␈αcan␈αreplace␈αthe␈αvariable
␈↓ ↓H␈↓lookup␈αwith␈αa␈αsimple␈α
address␈αcalculation.␈αThis␈αis␈α
partly␈αdue␈αto␈αAlgol's␈α
use␈αof␈αstatic␈αbinding␈↓π 186␈↓␈α
and
␈↓ ↓H␈↓partly␈α∩due␈α∩to␈α∩its␈α⊃restrictions␈α∩on␈α∩procedure-valued␈α∩variables.␈α⊃ These␈α∩kinds␈α∩of␈α∩restrictions␈α⊃allow
␈↓ ↓H␈↓Fortran and Algol compilers to produce efficient code.
␈↓ ↓H␈↓In␈α⊂the␈α⊂most␈α⊂general␈α⊂uses␈α⊂of␈α⊂LISP,␈α⊂both␈α⊂the␈α⊂quality␈α⊂and␈α⊂the␈α⊂quantity␈α⊂of␈α⊂variables␈α⊃can␈α⊂change.
␈↓ ↓H␈↓Arbitrary␈α
properties␈α
can␈αbe␈α
associated␈α
with␈αatoms␈α
at␈α
run-time.␈α Indeed,␈α
the␈α
symbol␈αtable␈α
mechanism
␈↓ ↓H␈↓of␈α⊂LISP␈α⊂is␈α⊂more␈α⊂reminiscent␈α⊂of␈α⊂that␈α⊂associated␈α⊂with␈α⊂the␈α⊂Fortran␈α⊂or␈α⊂Algol␈α⊂compiler.␈α⊃ For␈α⊂these
␈↓ ↓H␈↓languages␈α
it␈α
is␈α
the␈α
compiler␈α
which␈αperforms␈α
the␈α
mapping␈α
from␈α
source␈α
language␈α
to␈αrunning␈α
machine
␈↓ ↓H␈↓code.␈α∂ It␈α∂is␈α∂the␈α∂compiler's␈α∂responsibility␈α∞to␈α∂discover␈α∂the␈α∂properties␈α∂associated␈α∂with␈α∂each␈α∞variable.
␈↓ ↓H␈↓The␈αcompiler␈αcan␈αdo␈αthis␈αbecause␈αthe␈αsemantics␈αof␈αthe␈αlanguage␈αis␈αsuch␈αthat␈αat␈αcompile␈αtime␈αall,␈αor
␈↓ ↓H␈↓almost␈αall,␈αof␈αthe␈αproperties␈αof␈αthe␈αvariables␈αare␈α
known.␈α This␈αis␈αnot␈αtrue␈αfor␈αLISP.␈α In␈αgeneral␈α
you
␈↓ ↓H␈↓cannot␈αtell␈αuntil␈αrun␈αtime␈αwhat␈αthe␈αattributes␈αof␈αa␈αparticular␈αatom␈αare.␈α The␈αsituation␈αis␈αreally␈αeven
␈↓ ↓H␈↓worse␈α
than␈αthis.␈α
Since␈αprograms␈α
and␈αdata␈α
are␈αindistinguishable,␈α
we␈αcan␈α
construct␈αa␈α
list␈α
using␈αthe
␈↓ ↓H␈↓data␈α
structure␈α∞facilities␈α
and␈α
the␈α∞turn␈α
right␈α∞around␈α
and␈α
evaluate␈α∞that␈α
list␈α
as␈α∞a␈α
representation␈α∞of␈α
a
␈↓ ↓H␈↓LISP expression.
␈↓ ↓H␈↓However,␈α∞a␈α∂large␈α∞majority␈α∂of␈α∞LISP␈α∞computations␈α∂fall␈α∞into␈α∂a␈α∞much␈α∞more␈α∂disciplined␈α∞set,␈α∂and␈α∞for
␈↓ ↓H␈↓those␈α∂computations,␈α∂some␈α⊂of␈α∂the␈α∂ideas␈α⊂available␈α∂for␈α∂Fortran␈α⊂or␈α∂Algol␈α∂translators␈α⊂are␈α∂applicable.
␈↓ ↓H␈↓That␈α
is␈α
we␈α
don't␈α∞use␈α
all␈α
of␈α
the␈α∞generality␈α
available␈α
in␈α
the␈α∞language␈α
and␈α
we␈α
can␈α∞therefore␈α
reduce
␈↓ ↓H␈↓some␈α∀of␈α∀the␈α∀variable␈α∀look␈α∀up,␈α∀for␈α∃example.␈α∀ For␈α∀these␈α∀kinds␈α∀of␈α∀computations,␈α∀it␈α∃might␈α∀be
␈↓ ↓H␈↓appropriate␈αto␈αcompile␈αout␈αthe␈αunneeded␈α
generality.␈α There␈αare␈αLISP␈αcompilers,␈αtypically␈αwritten␈α
in
␈↓ ↓H␈↓LISP.␈αThey␈αcan␈αmake␈αmany␈αdecisions␈αat␈αcompile␈αtime␈αabout␈αthe␈αproperties␈αof␈αvariables;␈αand␈αgiven
␈↓ ↓H␈↓comparable␈α⊂information␈α⊂about␈α⊂a␈α⊂program's␈α∂characteristics␈α⊂can␈α⊂produce␈α⊂code␈α⊂comparable␈α⊂to␈α∂that
␈↓ ↓H␈↓produced by Algol and Fortran ([Fat 73]).
␈↓ ↓H␈↓In␈α⊂general,␈α⊂the␈α⊂compiled␈α⊂code␈α⊂will␈α⊂be␈α∂interspersed␈α⊂with␈α⊂calls␈α⊂on␈α⊂␈↓αeval␈↓␈α⊂because␈α⊂the␈α⊂compiler␈α∂just
␈↓ ↓H␈↓doesn't␈α∩know␈α∩what␈α∩to␈α∩do.␈α∩ This␈α∩implies␈α∩that␈α∩compiled␈α∩and␈α∩interpreted␈α∩code␈α∩must␈α∩be␈α∪able␈α∩to
␈↓ ↓H␈↓communicate␈α
with␈α
each␈αother.␈α
A␈α
piece␈α
of␈αcompiled␈α
code␈α
can␈α
call␈αa␈α
λ-expression␈α
or␈αconversely.␈α
The
␈↓ ↓H␈↓execution␈α∞of␈α
the␈α∞program␈α∞should␈α
be␈α∞totally␈α∞transparent␈α
as␈α∞to␈α∞whether␈α
any,␈α∞or␈α∞all,␈α
or␈α∞none␈α∞of␈α
the
␈↓ ↓H␈↓functions␈αare␈αcompiled.␈α This␈αmeans␈αthat␈αthe␈αcalling␈αsequences␈αfor␈αboth␈αkinds␈αof␈αfunctions␈αmust␈αbe
␈↓ ↓H␈↓compatible.␈αLess␈αobvious␈αand␈αby␈αfar␈αmore␈αtroublesome,␈αis␈αthe␈αcommunication␈αof␈αthe␈αvalues␈αof␈αfree
␈↓ ↓H␈↓variables.␈α≠The␈α≠next␈α≤chapter␈α≠of␈α≠the␈α≠text␈α≤discusses␈α≠the␈α≠run-time␈α≠behavior␈α≤required␈α≠for
␈↓ ↓H␈↓implementations of LISP-like languages and will include a discussion of LISP compilers.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 186␈↓ This is another benefit of referential transparency (page 156).
␈↓ ↓H␈↓␈↓↓6.␈↓ λwDynamic Structure 283␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓↓CHAPTER 6
␈↓ ↓H␈↓↓␈↓ ∧7THE DYNAMIC STRUCTURE OF LISP␈↓
␈↓ ↓H␈↓␈↓ ¬`␈↓↓6.1 Introduction␈↓
␈↓ ↓H␈↓As␈α∀things␈α∪presently␈α∀stand␈α∪we␈α∀have␈α∀developed␈α∪the␈α∀basic␈α∪static␈α∀structure␈α∪of␈α∀a␈α∀LISP␈α∪machine
␈↓ ↓H␈↓consisting␈α
of␈α
␈↓αeval␈↓␈αand␈α
its␈α
subfunctions,␈α
the␈αI/O␈α
routines,␈α
the␈α
garbage␈αcollector,␈α
and␈α
an␈αinitial␈α
symbol
␈↓ ↓H␈↓table␈α
which␈α∞contains␈α
the␈α∞constants.␈α
These␈α∞constants␈α
include␈α∞primitive␈α
functions,␈α∞␈↓αT␈↓␈α
and␈α∞␈↓αNIL␈↓,␈α
and
␈↓ ↓H␈↓usually␈α↔a␈α↔collection␈α↔of␈α↔utility␈α↔functions␈α↔like␈α↔␈↓αappend␈↓,␈α↔and␈α↔␈↓αreverse␈↓.␈α↔We␈α↔have␈α↔two␈α↔areas␈α⊗of
␈↓ ↓H␈↓memory: pointer space, and full word space.
␈↓ ↓H␈↓Expressions␈α∞to␈α∞be␈α∞evaluated␈α∞are␈α∞read␈α∞in,␈α
converted␈α∞to␈α∞list␈α∞structure,␈α∞and␈α∞evaluated␈α∞by␈α∞␈↓αeval␈↓.␈α
The
␈↓ ↓H␈↓evaluation␈α_entails␈α_traversing␈α_the␈α_S-expression␈α_representation␈α_of␈α_the␈α_form,␈α_interpreting␈α_the
␈↓ ↓H␈↓information␈αfound␈α
there␈αas␈α
LISP␈α"instructions".␈α
We␈αhave␈α
discussed␈αsome␈α
basic␈αdata␈α
structures␈αfor
␈↓ ↓H␈↓implementation␈α∪of␈α∀λ-bindings␈α∪and␈α∀evaluation,␈α∪but␈α∀we␈α∪have␈α∀said␈α∪little␈α∀about␈α∪how␈α∀the␈α∪actual
␈↓ ↓H␈↓execution␈α
of␈αthe␈α
expression␈αtakes␈α
place.␈α
The␈αessential␈α
ingredient␈αinvolved␈α
here␈αis␈α
the␈α
handling␈αof
␈↓ ↓H␈↓control␈α⊂--␈α⊂the␈α⊂dynamics␈α⊂of␈α⊂LISP␈α⊂execution.␈α⊂ For␈α⊂example,␈α⊂how␈α⊂can␈α⊂we␈α⊂implement␈α∂call-by-value,
␈↓ ↓H␈↓parameter␈αpassing,␈αrecursion,␈αand␈αconditional␈αexpressions?␈α At␈αa␈αhigh␈αlevel,␈αthe␈αoriginal␈α␈↓αeval-apply␈↓
␈↓ ↓H␈↓pair␈α
of␈αSection 3.5␈α
␈↓↓does␈↓␈αdescribe␈α
the␈α
evaluation␈αmechanism.␈α
Given␈αthe␈α
data␈αstructure␈α
representation
␈↓ ↓H␈↓of␈αan␈αexpression,␈αwe␈αcan␈αmechanically␈αperform␈αthe␈αtransformations␈αimplied␈αin␈αthe␈α␈↓αeval-apply␈↓␈αpair.
␈↓ ↓H␈↓Even␈αmore␈αof␈αthe␈αdetail␈αis␈αmade␈αexplicit␈αin␈αthe␈αlater␈αevaluators␈αof␈αSection 4.6␈αthrough␈αSection 4.8.
␈↓ ↓H␈↓However␈αwe␈αmust␈αstill␈αimplement␈αthese␈αevaluators␈αon␈αa␈α"real"␈αmachine␈αand,␈αunless␈αthe␈αevaluator␈αis
␈↓ ↓H␈↓built␈αinto␈αthe␈αhardware,␈αwe␈αmust␈αexpress␈αthe␈αevaluator␈αin␈αterms␈αof␈αmore␈αprimitive␈αoperations.␈αFor
␈↓ ↓H␈↓example,␈αwe␈αcannot␈α
"implement"␈αrecursion␈αby␈α
␈↓↓using␈↓␈αrecursion;␈αwe␈αmust␈α
express␈αthat␈αidea␈α
in␈αterms
␈↓ ↓H␈↓of␈αlower␈α
level␈αoperations.␈α
Obviously␈αthis␈α
decomposition␈αmust␈α
stop␈αsomewhere.␈α
As␈αJ. McCarthy␈α
once
␈↓ ↓H␈↓said: "Nothing can be explained to a stone"; we must assume certain primitives are known.
␈↓ ↓H␈↓In␈αthis␈αchapter␈αwe␈αwill␈αdiscuss␈αtwo␈α
layers␈αof␈α"primitive␈αoperations"␈αor␈α␈↓↓instructions␈↓.␈αOne␈α
layer␈αwill
␈↓ ↓H␈↓correspond␈α
to␈αtraditional␈α
hardware,␈α
and␈αanother␈α
layer␈αwill␈α
correspond␈α
to␈αthe␈α
primitives␈α
which␈αwe
␈↓ ↓H␈↓derive␈α
from␈α
the␈αevaluator␈α
of␈α
Section 4.8.␈α Here␈α
we␈α
discuss␈αthe␈α
primitives␈α
of␈αthat␈α
section␈α
as␈αthe␈α
basis
␈↓ ↓H␈↓for␈α∩a␈α⊃machine␈α∩which␈α⊃executes␈α∩LISP␈α∩expressions.␈α⊃ We␈α∩can␈α⊃describe␈α∩the␈α⊃evaluation␈α∩of␈α∩a␈α⊃LISP
␈↓ ↓H␈↓expression␈α∂as␈α∂the␈α∂execution␈α∂of␈α∂a␈α⊂sequence␈α∂of␈α∂these␈α∂instructions.␈α∂Both␈α∂operations␈α⊂are␈α∂equivalent:
␈↓ ↓H␈↓either␈αevaluate␈αthe␈αexpression␈αor␈αexecute␈αthe␈αinstruction␈αsequence.␈α There␈αare␈αcommon␈αinstances␈αin
␈↓ ↓H␈↓which␈α
the␈α
execution␈αof␈α
the␈α
instructions␈α
can␈αbe␈α
considered␈α
to␈α
be␈α"more␈α
efficient"␈α
than␈αthe␈α
evaluation
␈↓ ↓H␈↓of the expression.
␈↓ ↓H␈↓For␈α⊃example,␈α⊂consider␈α⊃the␈α⊂access␈α⊃to␈α⊂a␈α⊃local␈α⊃variable.␈α⊂Each␈α⊃such␈α⊂access␈α⊃is␈α⊂to␈α⊃the␈α⊃same␈α⊂location
␈↓ ↓H␈↓relative␈αto␈αthe␈αlocal␈αenvironment.␈αThat␈α
relative␈αlocation␈αcan␈αbe␈αcomputed␈αeasily,␈αbut␈α
the␈αevaluator
␈↓ ↓H␈↓␈↓↓284 Dynamic Structure␈↓ 76.1␈↓
␈↓ ↓H␈↓will␈α∞use␈α∞a␈α∞version␈α∞of␈α∞␈↓αlookup␈↓␈α∞for␈α∞every␈α∞access.␈α∞ We␈α∞␈↓↓must␈↓␈α∞resort␈α∞to␈α∞␈↓αlookup␈↓␈α∞for␈α∂non-local␈α∞variables,
␈↓ ↓H␈↓since␈α∪LISP␈α∪uses␈α∪dynamic␈α∪binding␈α∪and␈α∪the␈α∪activation␈α∪environment␈α∪will␈α∪typically␈α∪effect␈α∩which
␈↓ ↓H␈↓binding␈αis␈α
accessible,␈αbut␈α
since␈αthe␈αlocation␈α
of␈αany␈α
local␈αvariable␈αis␈α
computable,␈αwe␈α
should␈αexploit
␈↓ ↓H␈↓that knowledge when executing our programs.
␈↓ ↓H␈↓Several␈αexamples␈αalso␈αarise␈αin␈αthe␈αevaluation␈αof␈αa␈α␈↓αprog␈↓.␈αFor␈αexample␈αa␈αloop␈αtypically␈αconsists␈αof␈αa
␈↓ ↓H␈↓static␈↓π 187␈↓␈α∂sequence␈α∞of␈α∂statements.␈α∞Each␈α∂time␈α∂around␈α∞the␈α∂loop␈α∞an␈α∂evaluator␈α∞will␈α∂execute␈α∂the␈α∞same
␈↓ ↓H␈↓sequence␈α∞of␈α∞instructions.␈α∞It␈α∞would␈α∞be␈α∞faster␈α∞to␈α∞simply␈α∞execute␈α∞the␈α∞sequence␈α∞of␈α∂instructions␈α∞rather
␈↓ ↓H␈↓than␈αre-interpret␈αeach␈αexpression.␈αA␈αrelated␈αefficiency␈αinvolves␈αthe␈αexecution␈αof␈α␈↓αgo␈↓.␈αWe␈αassumed␈αin
␈↓ ↓H␈↓Section 4.8␈α∞that␈α∞the␈α∞evaluator␈α∞will␈α∞either␈α∞lookup␈α∞the␈α∞label␈α∞by␈α∞searching␈α∞the␈α∞body␈α∞of␈α∞the␈α∞␈↓αprog␈↓␈α∞or,
␈↓ ↓H␈↓perhaps␈α∞more␈α∞efficiently,␈α∞searching␈α∞a␈α∞computed␈α∞␈↓αgo_list␈↓.␈α∞Either␈α∞case␈α∞requires␈α∞a␈α∞search.␈α∞ If␈α∂we␈α∞can
␈↓ ↓H␈↓replace␈αthe␈αbody␈αof␈αa␈αloop␈αwith␈αa␈αsequence␈αof␈αprimitive␈αinstructions,␈αthen␈αwe␈αcan␈αreplace␈αa␈α␈↓αgo␈↓␈αwith
␈↓ ↓H␈↓a␈α⊂transfer␈α⊂of␈α⊂control␈α⊂to␈α⊂the␈α⊂beginning␈α∂of␈α⊂an␈α⊂appropriate␈α⊂block␈α⊂of␈α⊂instructions.␈α⊂Such␈α⊂a␈α∂transfer
␈↓ ↓H␈↓operation␈α∂would␈α∂be␈α∂one␈α∂of␈α∂our␈α∂instructions.␈α⊂A␈α∂problem␈α∂related␈α∂to␈α∂the␈α∂execution␈α∂of␈α∂loops␈α⊂is␈α∂the
␈↓ ↓H␈↓␈↓↓recognition␈↓␈α∪of␈α∩a␈α∪loop.␈α∩ The␈α∪extent␈α∩of␈α∪--or␈α∩even␈α∪the␈α∩presence␈α∪of--␈α∩a␈α∪loop␈α∩which␈α∪the␈α∪user␈α∩is
␈↓ ↓H␈↓controlling␈α⊃by␈α⊂tests␈α⊃and␈α⊂␈↓αgo␈↓'s␈α⊃may␈α⊂be␈α⊃difficult␈α⊃to␈α⊂discover.␈α⊃ If␈α⊂a␈α⊃loop␈α⊂is␈α⊃controlled␈α⊃by␈α⊂language
␈↓ ↓H␈↓constructs␈α∂(␈↓αwhile, do, repeat␈↓, etc.)␈α∞then␈α∂the␈α∞interpreter␈α∂should␈α∞have␈α∂some␈α∞chance␈α∂of␈α∂improving␈α∞the
␈↓ ↓H␈↓execution␈α
of␈α
the␈α
loop.␈α This,␈α
perhaps,␈α
is␈α
another␈α
good␈αreason␈α
for␈α
removing␈α
control␈α
of␈αiteration␈α
from
␈↓ ↓H␈↓the hands of the programmer.
␈↓ ↓H␈↓The␈αtranslation␈αof␈α
an␈αexpression␈αinto␈α
a␈αsequence␈αof␈αinstructions␈α
is␈αnot␈αwithout␈α
cost.␈αIf␈αwe␈α
wish␈αto
␈↓ ↓H␈↓evaluate␈α
a␈αsimple␈α
expression␈αonly␈α
once,␈αthen␈α
direct␈αevaluation␈α
is␈αusually␈α
less␈α
time-consuming␈αthan
␈↓ ↓H␈↓translation␈αplus␈α
execution.␈α However␈αexpressions␈α
subjected␈αto␈αrepeated␈α
evaluation␈αcan␈αprofitably␈α
be
␈↓ ↓H␈↓translated into instructions and executed.
␈↓ ↓H␈↓The␈α∞translation␈α
part␈α∞of␈α
the␈α∞process␈α∞which␈α
we␈α∞have␈α
been␈α∞describing␈α∞is␈α
called␈α∞a␈α
␈↓↓compiler␈↓.␈α∞ It␈α∞is␈α
a
␈↓ ↓H␈↓mapping␈α⊃from␈α∩the␈α⊃LISP␈α∩expressions␈α⊃to␈α∩a␈α⊃sequence␈α∩of␈α⊃instructions.␈α∩When␈α⊃the␈α∩instructions␈α⊃are
␈↓ ↓H␈↓carried␈αout␈αthey␈αwill␈αhave␈αthe␈αsame␈αeffect␈αas␈α␈↓αeval␈↓,␈αinterpreting␈αthe␈αoriginal␈αexpression.␈α A␈αcompiler
␈↓ ↓H␈↓is␈α
a␈α
useful␈α
tool␈α
for␈αincreasing␈α
the␈α
speed␈α
of␈α
execution.␈α
J.␈αMcCarthy␈α
says␈α
a␈α
compiler␈α
allows␈α
you␈αto
␈↓ ↓H␈↓look␈α
␈↓↓before␈↓␈α
you␈α
leap;␈α
we␈α
will␈α
show␈α
that␈α
we␈α
can␈α
look␈α
␈↓↓as␈↓␈α
we␈α
leap.␈α
That␈α
is,␈α
we␈α
can␈α
compile␈α
instructions
␈↓ ↓H␈↓as␈α
we␈αevaluate␈α
expressions;␈αif␈α
the␈α
expression␈αis␈α
evaluated␈αagain␈α
then␈α
we␈αexecute␈α
the␈αfaster␈α
compiled
␈↓ ↓H␈↓version.
␈↓ ↓H␈↓The␈α⊂relationship␈α⊂between␈α⊂compilation␈α⊂and␈α⊃interpretation␈α⊂should␈α⊂be␈α⊂coming␈α⊂more␈α⊃apparent:␈α⊂the
␈↓ ↓H␈↓interpreter␈α
performs␈αthe␈α
evaluation;␈α
the␈αcompiler␈α
emits␈α
instructions␈αwhich␈α
when␈α
executed␈αproduce
␈↓ ↓H␈↓the␈αsame␈αcomputational␈αeffect␈αas␈αthe␈αevaluator.␈α Since␈αthe␈αcode␈αproduced␈αby␈αthe␈αcompiler␈αis␈αeither
␈↓ ↓H␈↓in␈αmachine␈αlanguage␈αor␈αin␈α
a␈αform␈αcloser␈αto␈αthe␈αmachine␈α
than␈αthe␈αsource␈αprogram,␈αwe␈α
can␈αexecute
␈↓ ↓H␈↓the␈αcode␈α
much␈αfaster.␈αA␈α
speed-up␈αfactor␈α
of␈αthirty␈αto␈α
fifty␈αis␈α
not␈αuncommon.␈α Also␈α
in␈αLISP␈αwe␈α
know
␈↓ ↓H␈↓that␈α⊂programs␈α⊂are␈α⊂stored␈α⊂as␈α⊂S-expressions.␈α∂ Our␈α⊂compiled␈α⊂code␈α⊂will␈α⊂be␈α⊂machine␈α⊂language,␈α∂thus
␈↓ ↓H␈↓freeing␈αa␈αlarge␈αquantity␈αof␈αS-expression␈αstorage.␈αThis␈αwill␈αusually␈αmake␈αgarbage␈αcollection␈αless␈αtime
␈↓ ↓H␈↓consuming.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 187␈↓␈αBy␈αstatic␈αwe␈αmean␈αthat␈αthe␈αactual␈αexpressions␈αdo␈αnot␈αchange␈αduring␈αexecution.␈αUsing␈αthe␈αfact
␈↓ ↓H␈↓that␈α
LISP␈αprograms␈α
are␈αdata␈α
structures␈αand␈α
using␈αsome␈α
marginal␈αprogramming␈α
techniques␈α␈↓αrplaca␈↓
␈↓ ↓H␈↓and␈α∞␈↓αrplacd␈↓␈α∞(Section 7.6)␈α∞we␈α∞can␈α∞in␈α∞fact␈α∞write␈α∞self␈α∞modifying␈α∞programs.␈α∞However,␈α∞such␈α∞practice␈α
is
␈↓ ↓H␈↓not common.
␈↓ ↓H␈↓␈↓↓6.1␈↓ OIntroduction 285␈↓
␈↓ ↓H␈↓Why␈α
not␈αcompile␈α
all␈αprograms?␈α
We␈αalready␈α
have␈α
seen␈αthat␈α
we␈αcan␈α
␈↓αcons␈↓-up␈αnew␈α
expressions␈α
to␈αbe
␈↓ ↓H␈↓evaluated␈α⊂while␈α⊂we␈α⊂are␈α⊂running.␈α⊂Still␈α⊃we␈α⊂can␈α⊂force␈α⊂even␈α⊂those␈α⊂expressions␈α⊂through␈α⊃a␈α⊂compiler
␈↓ ↓H␈↓before␈α⊃execution␈↓π 188␈↓.␈α⊃The␈α⊃answer,␈α⊃rather,␈α⊃is␈α⊃that␈α⊃for␈α⊃debugging␈α⊃and␈α⊃editing␈α⊃of␈α⊃programs␈α∩it␈α⊃is
␈↓ ↓H␈↓extremely convenient to have a structured representation of the program in memory.
␈↓ ↓H␈↓This␈α∃structured␈α∃representation␈α∃also␈α∃simplifies␈α∃the␈α∀discussion␈α∃of␈α∃compilation.␈α∃ It␈α∃is␈α∃true␈α∀that
␈↓ ↓H␈↓compilers␈α∩can␈α∩be␈α∩written␈α∩to␈α∩go␈α⊃directly␈α∩from␈α∩M-expression␈α∩representation␈α∩to␈α∩internal␈α⊃machine
␈↓ ↓H␈↓code␈↓π 189␈↓.␈α∂ Conventional␈α∞compiler␈α∂discussions␈α∂include␈α∞description␈α∂of␈α∞the␈α∂syntax␈α∂analysis␈α∞problems,
␈↓ ↓H␈↓for␈αwe␈αcannot␈αcompile␈αcode␈αuntil␈αwe␈αknow␈α
what␈αthe␈αsyntactic␈αstructure␈αof␈αthe␈αprogram␈αis.␈α
However,
␈↓ ↓H␈↓syntax␈α
analysis␈αis␈α
really␈α
irrelevant␈αfor␈α
a␈α
clear␈αunderstanding␈α
of␈α
the␈αimplementation␈α
of␈α
a␈αcompiler.
␈↓ ↓H␈↓Assuming␈α
the␈α∞existence␈α
of␈α
the␈α∞structured␈α
representation,␈α
the␈α∞compiler␈α
is␈α
conceptually␈α∞very␈α
simple.
␈↓ ↓H␈↓This␈α
structured␈αrepresentation␈α
is␈αthe␈α
S-expr␈α
representation␈αin␈α
LISP␈αand␈α
resembles␈αa␈α
parse␈α
tree␈αin
␈↓ ↓H␈↓other␈α
languages.␈α
When␈α
we␈α
wish␈α
to␈α
run␈α∞the␈α
program␈α
at␈α
top␈α
speed,␈α
we␈α
can␈α
compile␈α∞the␈α
programs.
␈↓ ↓H␈↓The␈αcompiler␈α
can␈αthen␈αtranslate␈α
the␈αabstract␈αrepresentation␈α
of␈αthe␈αprogram␈α
into␈αmachine␈αcode.␈α
We
␈↓ ↓H␈↓shall say more about this view of programming later.
␈↓ ↓H␈↓We␈αshall␈αexploit␈α
the␈αanalogy␈αbetween␈α
compilers␈αand␈αevaluators␈αwhen␈α
we␈αwrite␈αthe␈α
LISP␈αfunction,
␈↓ ↓H␈↓␈↓αcompile␈↓,␈α
which␈α
will␈α
implement␈α
the␈α
compiler.␈α
We␈α
shall␈α
do␈α
this␈α
in␈α
two␈α
ways.␈α
First,␈α
the␈α∞structure␈α
of
␈↓ ↓H␈↓the␈α
␈↓αcompile␈↓␈α∞function␈α
and␈α∞its␈α
subfunctions␈α
will␈α∞be␈α
written␈α∞to␈α
capitalize␈α
on␈α∞the␈α
knowledge␈α∞we␈α
have
␈↓ ↓H␈↓acquired␈αfrom␈α
writing␈αevaluators.␈αSecond,␈α
we␈αwill␈αattempt␈α
to␈αabstract␈αfrom␈α
the␈αspecific␈αcompiler␈α
the
␈↓ ↓H␈↓essence␈α
of␈α
all␈α
LISP␈α
compilers␈α
without␈α
losing␈α
all␈α
of␈α
the␈α
details.␈α
This␈α
second␈α
task␈α
is␈α
more␈α
difficult
␈↓ ↓H␈↓because␈α∞we␈α∞have␈α∞to␈α∞separate␈α∞two␈α
representations␈α∞from␈α∞the␈α∞specific␈α∞compiler.␈α∞We␈α∞are␈α
representing
␈↓ ↓H␈↓forms␈α∂as␈α∞data␈α∂structures,␈α∞and␈α∂we␈α∞are␈α∂also␈α∞dealing␈α∂with␈α∞the␈α∂representation␈α∞of␈α∂a␈α∂specific␈α∞machine.
␈↓ ↓H␈↓The␈α
task␈α
␈↓↓is␈↓␈α
worth␈α
pursuing␈αsince␈α
we␈α
wish␈α
to␈α
write␈αdifferent␈α
compilers␈α
for␈α
the␈α
same␈α
machine␈αand
␈↓ ↓H␈↓also a single compiler capable of easy transportation to other machines.
␈↓ ↓H␈↓The␈αinput␈αto␈α␈↓αcompile␈↓␈αis␈αthe␈αrepresentation␈αof␈αa␈αLISP␈αfunction;␈αthe␈αoutput␈αis␈αa␈αlist␈αwhich␈αrepresents
␈↓ ↓H␈↓a␈αsequence␈αof␈αmachine␈αinstructions.␈α Assume␈αthat␈αwe␈αhave␈αLISP␈αrunning␈αon␈α␈↓ Brand␈αX␈↓␈αmachine,
␈↓ ↓H␈↓and␈α
we␈α
have␈α
written␈α∞a␈α
␈↓αcompile␈↓␈α
which␈α
produces␈α
code␈α∞for␈α
␈↓ Brand␈α
X␈↓␈α
machine.␈α
Then␈α∞perform␈α
the
␈↓ ↓H␈↓following sequence of steps:
␈↓ ↓H␈↓␈↓ β( 1. Create the S-expression form of ␈↓αcompile␈↓.
␈↓ ↓H␈↓␈↓ β( 2. Introduce this translation into the machine, defining ␈↓αcompile␈↓.
␈↓ ↓H␈↓␈↓ β( 3. Ask LISP to evaluate: ␈↓αcompile[COMPILE]␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 188␈↓␈αThere␈αare,␈αhowever,␈αprograms␈αwhich␈αsimply␈α␈↓↓cannot␈↓␈αbe␈αcompiled.␈αThe␈αmost␈αobscene␈αexamples
␈↓ ↓H␈↓involve␈α∞self-modifying␈α
programs;␈α∞that␈α
is,␈α∞programs␈α
which␈α∞modify␈α
their␈α∞representation␈α
in␈α∞order␈α
to
␈↓ ↓H␈↓affect the course of interpretation. An example is reluctantly given on page 363.
␈↓ ↓H␈↓␈↓π 189␈↓␈α
The␈αcompilers␈α
which␈αperform␈α
in␈α
this␈αmanner␈α
are␈αcalled␈α
sytnax␈α
directed␈αcompilers.␈α
They␈αare␈α
an
␈↓ ↓H␈↓instance␈α∞of␈α∞a␈α∞computational␈α∞scheme␈α∞called␈α∞syntax␈α∞directed␈α∞computation;␈α∞the␈α∞idea␈α∞is␈α∞based␈α∂on␈α∞the
␈↓ ↓H␈↓observation␈α∪that␈α∀many␈α∪algorithms␈α∪parallel␈α∀the␈α∪underlying␈α∪data␈α∀structure.␈α∪We␈α∪have␈α∀seen␈α∪this
␈↓ ↓H␈↓behavior␈α
frequently␈αin␈α
our␈α
data␈αstructure␈α
algorithms.␈αFor␈α
application␈α
to␈αcmpiling␈α
and␈α
parsing␈αsee
␈↓ ↓H␈↓[Gri 71] or [Aho 72].
␈↓ ↓H␈↓␈↓↓286 Dynamic Structure␈↓ 76.1␈↓
␈↓ ↓H␈↓Since␈α
␈↓αcompile␈↓␈α
compiles␈α
code␈α
for␈α∞␈↓ Brand␈α
X␈↓␈α
machine,␈α
it␈α
translates␈α
the␈α∞S-expression␈α
representation
␈↓ ↓H␈↓of␈α∪its␈α∪argument␈α∪into␈α∪machine␈α∀code.␈α∪Therefore␈α∪the␈α∪output␈α∪of␈α∀step␈α∪3␈α∪is␈α∪a␈α∪list␈α∀of␈α∪instructions
␈↓ ↓H␈↓representing the translation of ␈↓αcompile␈↓. That is, step 3 compiles the compiler.
␈↓ ↓H␈↓A␈αtechnique␈αcalled␈α␈↓↓bootstrapping␈↓␈αis␈αclosely␈αrelated␈αto␈αthe␈αprocess␈αjust␈αdescribed.␈α To␈αillustrate␈αthis
␈↓ ↓H␈↓idea,␈α∩assume␈α∩that␈α∩we␈α∩have␈α∩LISP␈α∩and␈α∪its␈α∩compiler␈α∩running␈α∩on␈α∩␈↓ Brand X␈↓,␈α∩and␈α∩we␈α∪wish␈α∩to
␈↓ ↓H␈↓implement␈α
LISP␈αon␈α
␈↓ Brand␈αY␈↓.␈α
If␈αwe␈α
have␈αbeen␈α
careful␈αin␈α
our␈αencoding␈α
of␈αthe␈α
␈↓αcompile␈↓␈αfunction
␈↓ ↓H␈↓then␈α␈↓↓most␈↓␈α
of␈α␈↓αcompile␈↓␈α
is␈αmachine␈α
independent;␈αthat␈α
is,␈αit␈α
deals␈αmostly␈α
with␈αthe␈α
structure␈αof␈αthe␈α
LISP
␈↓ ↓H␈↓expression␈α
and␈α
only␈α
in␈αa␈α
few␈α
places␈α
deals␈αwith␈α
the␈α
structure␈α
of␈αa␈α
particular␈α
machine.␈α
As␈α
we␈αwill
␈↓ ↓H␈↓see,␈α∩this␈α∩is␈α∩not␈α∩an␈α∩unrealisitc␈α∩assumption.␈α⊃ Notice␈α∩that␈α∩this␈α∩is␈α∩one␈α∩of␈α∩our␈α∩early␈α⊃programming
␈↓ ↓H␈↓admonitions:␈α(encode␈α(algorithms␈α(in␈α(a␈α(representation-independent␈α(style␈α)and␈α(include
␈↓ ↓H␈↓representation-dependent␈α
routines␈α
to␈α
interface␈α
with␈α
the␈α
program.␈α
Changing␈α
representations␈α
simply
␈↓ ↓H␈↓requires␈α∂changing␈α∞those␈α∂simpler␈α∞subfunctions.␈α∂Here␈α∂the␈α∞representations␈α∂are␈α∞of␈α∂machines␈α∂and␈α∞the
␈↓ ↓H␈↓algorithm is a compiling function for LISP.
␈↓ ↓H␈↓Let␈α⊃us␈α∩call␈α⊃those␈α∩parts␈α⊃of␈α∩the␈α⊃compiler␈α⊃which␈α∩deal␈α⊃with␈α∩the␈α⊃machine,␈α∩the␈α⊃code␈α∩generators␈α⊃or
␈↓ ↓H␈↓instruction␈α
generators.␈α
Now␈α∞if␈α
we␈α
understand␈α∞the␈α
machine␈α
organization␈α
of␈α∞brands␈α
␈↓ X␈↓␈α
and␈α∞␈↓ Y␈↓␈α
then
␈↓ ↓H␈↓for␈αany␈α
instruction␈αon␈α
␈↓ Brand X␈↓␈αwe␈α
should␈αbe␈α
able␈αto␈α
give␈αa␈α
sequence␈αof␈α
instructions␈αhaving␈α
the
␈↓ ↓H␈↓equivalent␈αeffect␈αon␈α␈↓ Brand Y␈↓.␈αWe␈αcan␈αchange␈αthe␈αinstruction␈αgenerators␈αin␈α␈↓αcompile␈↓␈αto␈αgenerate
␈↓ ↓H␈↓instructions␈α
which␈α
run␈α
on␈α
␈↓ Brand Y␈↓.␈α
We␈α
would␈α
have␈α
a␈α
␈↓αcompile␈↓␈α
function,␈α
call␈α
it␈α␈↓αcompile*␈↓,␈α
running
␈↓ ↓H␈↓on␈α
␈↓ X␈↓␈αand␈α
producing␈αinstructions␈α
for␈α␈↓ Y␈↓.␈α
Take␈αthe␈α
S-expr␈αrepresentations␈α
of␈α␈↓αeval,␈α
apply,␈αread,␈α
print,
␈↓ ↓H␈↓αcompile*,...␈↓␈αetc.␈α and␈αpass␈αthese␈αthrough␈α␈↓αcompile*␈↓;␈αit␈αthis␈αway␈αwe␈αgenerate␈αa␈αlarge␈αsegment␈αof␈αa␈α
LISP
␈↓ ↓H␈↓system␈α
which␈α
will␈α
run␈α
on␈α
␈↓ Y␈↓.␈α
Certain␈α
primitives␈α
will␈α
have␈α
to␈α
be␈α
supplied␈α
to␈α
run␈α
these␈α
instructions␈α
on
␈↓ ↓H␈↓␈↓ Y␈↓, but a very large part of LISP can be bootstrapped from ␈↓ X␈↓ to ␈↓ Y␈↓.
␈↓ ↓H␈↓Given␈α
a␈α
compiler␈αand␈α
interpreter␈α
for␈α
a␈αlanguage␈α
␈↓εL␈↓β1␈↓␈α
we␈αcan␈α
also␈α
bootstrap␈α
␈↓εL␈↓β1␈↓␈αto␈α
a␈α
language␈α␈↓εL␈↓β2␈↓.␈α
We
␈↓ ↓H␈↓express␈α⊃the␈α⊃interpreter␈α⊃for␈α⊃␈↓εL␈↓β2␈↓␈α⊂as␈α⊃a␈α⊃program␈α⊃in␈α⊃␈↓εL␈↓β1␈↓.␈α⊃We␈α⊂can␈α⊃then␈α⊃execute␈α⊃programs␈α⊃in␈α⊃␈↓εL␈↓β2␈↓␈α⊂by
␈↓ ↓H␈↓interpreting␈αthe␈α
␈↓εL␈↓β2␈↓␈αinterpreter.␈αWe␈α
can␈αimprove␈α
efficiency␈αby␈αcompiling␈α
the␈α␈↓εL␈↓β2␈↓␈αevaluator.␈α
Perhaps
␈↓ ↓H␈↓we can express the ␈↓εL␈↓β2␈↓ compiler in ␈↓εL␈↓β1␈↓ or ␈↓εL␈↓β2␈↓; in either case we can then compile that compiler.
␈↓ ↓H␈↓This␈αchapter␈αwill␈αdeal␈αwith␈αthe␈αimplementation␈αof␈αthe␈αcontrol␈αstructures␈αof␈αLISP.␈αWe␈αwill␈αdescribe
␈↓ ↓H␈↓implementations␈α∞of␈α∞these␈α∞features␈α∂as␈α∞we␈α∞develop␈α∞compilers␈α∞for␈α∂LISP.␈α∞ This␈α∞use␈α∞of␈α∂compilers␈α∞has
␈↓ ↓H␈↓several motivations:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α∃To␈α∃describe␈α∃the␈α∃compiler␈α∃we␈α∃must␈α∃carefully␈α∃define␈α∃the␈α∃machine␈α∃which␈α∃will␈α∃execute␈α∃the
␈↓ ↓H␈↓␈↓ ↓xinstructions␈α⊃which␈α⊃the␈α⊃compiler␈α⊃produces.␈α∩ The␈α⊃instructions␈α⊃generated␈α⊃by␈α⊃the␈α∩compiler␈α⊃will
␈↓ ↓H␈↓␈↓ ↓xreference␈α∞the␈α∞control␈α∞primitives␈α∞of␈α∞the␈α∞machine,␈α∂so␈α∞we␈α∞might␈α∞as␈α∞well␈α∞build␈α∞a␈α∞compiler␈α∂at␈α∞the
␈↓ ↓H␈↓␈↓ ↓xsame time we show the dynamic structure of LISP.
␈↓ ↓H␈↓␈↓↓2.␈↓␈αThe␈αdesign␈αof␈αthe␈αcompiler␈αshows␈αanother␈αnon-trivial␈αapplication␈αof␈αnon-numerical␈αcomputation.
␈↓ ↓H␈↓␈↓ ↓xAt the same time we will see how simple it is to describe such complex algorithms in LISP.
␈↓ ↓H␈↓␈↓↓3.␈↓␈α⊂It␈α∂will␈α⊂clearly␈α∂show␈α⊂the␈α∂relationship␈α⊂between␈α∂compilation␈α⊂and␈α∂evaluation.␈α⊂ That␈α∂is,␈α⊂the␈α∂LISP
␈↓ ↓H␈↓␈↓ ↓xfunction␈αrepresenting␈α
the␈αcompiler␈αwill␈α
very␈αclosely␈α
parallel␈αthe␈αstructure␈α
of␈αthe␈αinterpreter,␈α
␈↓αeval␈↓.
␈↓ ↓H␈↓␈↓ ↓xIf you understand ␈↓αeval␈↓, then the compiler is easy.
␈↓ ↓H␈↓␈↓↓6.1␈↓ OIntroduction 287␈↓
␈↓ ↓H␈↓As␈α∂in␈α∂the␈α∂previous␈α⊂chapter,␈α∂we␈α∂will␈α∂remain␈α∂as␈α⊂abstract␈α∂as␈α∂possible␈α∂without␈α∂losing␈α⊂the␈α∂necessary
␈↓ ↓H␈↓details.␈αA␈α
meaningful␈αdescription␈α
of␈αcompilers␈αentails␈α
an␈αunderstanding␈α
of␈αa␈α
machine,␈αso␈αbefore␈α
the
␈↓ ↓H␈↓actual␈αconstruction␈αof␈αthe␈αcompilers,␈αwe␈αwill␈αdescribe␈αa␈αsimple␈αmachine␈αwith␈αa␈αsufficient␈αinstruction
␈↓ ↓H␈↓set␈α∞to␈α∞handle␈α∞the␈α∞control␈α∞structures␈α∞of␈α∞LISP.␈α∞ First␈α∞we␈α∞will␈α∞review␈α∞and␈α∞expand␈α∞the␈α∂primitives␈α∞of
␈↓ ↓H␈↓Section 4.8, emphasizing their interpretation as machine instructions.
␈↓ ↓H␈↓␈↓ ¬-␈↓↓6.2 Primitives for LISP␈↓
␈↓ ↓H␈↓In␈α∞our␈α∞discussion␈α
of␈α∞the␈α∞evaluators␈α
in␈α∞Section 4.6␈α∞through␈α
Section 4.8␈α∞we␈α∞uncovered␈α∞more␈α
details
␈↓ ↓H␈↓involved␈α∂in␈α∂evaluation␈α∂of␈α∂LISP␈α∂expressions.␈α∂In␈α∂the␈α∂final␈α∂evaluator␈α∂we␈α∂identified␈α∂a␈α∂dozen␈α⊂or␈α∂so
␈↓ ↓H␈↓actions.␈α
The␈α∞underlying␈α
idea␈α∞was␈α
to␈α∞remove␈α
recursion␈α∞and␈α
replace␈α∞that␈α
implicit␈α∞control␈α
structure
␈↓ ↓H␈↓with very explicit actions, controlled by a simple loop:
␈↓ ↓H␈↓α␈↓ ¬_loop <= λ[[]prog[[]
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ε_l␈↓ ε8cont[]
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ε_␈↓ ε8go[l] ]]
␈↓ ↓H␈↓The␈αvariable␈α␈↓αcont␈↓␈αwas␈αa␈αfunctional␈αvariable,␈αbound␈αto␈αstates␈αand␈αset␈αto␈αthe␈αnext␈αstate␈αby␈αthe␈αaction
␈↓ ↓H␈↓of␈α∩the␈α∩current␈α∪state.␈α∩ This␈α∩observation␈α∪marks␈α∩the␈α∩beginning␈α∪of␈α∩a␈α∩machine␈α∪description.␈α∩What
␈↓ ↓H␈↓remains␈αto␈α
be␈αdone␈α
is␈αto␈α
separate␈αthe␈α
actions␈αof␈α
the␈αmachine␈α
from␈αthe␈α
instructions␈αit␈α
is␈αexecuting.
␈↓ ↓H␈↓That␈α⊂is,␈α⊂some␈α⊂of␈α⊂the␈α⊂details␈α⊂of␈α∂the␈α⊂state␈α⊂transformations␈α⊂deal␈α⊂with␈α⊂the␈α⊂bookkeeping␈α⊂which␈α∂the
␈↓ ↓H␈↓machine␈αis␈αdoing␈αto␈αdiscover␈αwhat␈αthe␈αexpression␈αis,␈αand␈αsome␈αof␈αthe␈αtransformations␈αperform␈αthe
␈↓ ↓H␈↓actual␈αevaluation␈αof␈αthe␈αexpression.␈αFor␈αexample,␈αthe␈αmanipulation␈αof␈α␈↓αfun␈↓␈αand␈α␈↓αargs␈↓␈αis␈αpart␈α
of␈αthe
␈↓ ↓H␈↓activity␈α∞to␈α∞discover␈α∞the␈α∞form␈α∞of␈α∞the␈α∞expression.␈α∞ The␈α∞execution␈α∞of␈α∞␈↓αsend␈↓␈α∞and␈α∞␈↓αreceive␈↓␈α∞are␈α∞involved
␈↓ ↓H␈↓with␈αthe␈αevaluation.␈α The␈αparts␈αof␈αthe␈αevaluator␈αinvolved␈αwith␈αthe␈αexecution␈αof␈αthe␈αexpression␈αare
␈↓ ↓H␈↓called␈α
the␈αinstructions␈α
of␈αthe␈α
machine.␈αSupplied␈α
with␈αan␈α
appropriate␈αexecution␈α
device,␈α
a␈αsequence
␈↓ ↓H␈↓of␈αthese␈αinstructions␈αcaptures␈αthe␈αmeaning␈αof␈αthe␈αevaluation␈αof␈αan␈αexpression.␈αIt␈αis␈αthe␈αbusiness␈αof
␈↓ ↓H␈↓this␈αsection␈αto␈αreview␈α
the␈αevaluators␈αand␈αextract␈α
a␈αsufficient␈αset␈αof␈α
instructions.␈α We␈αbegin␈αthat␈α
task
␈↓ ↓H␈↓with some examples, using ␈↓αpeval␈↓ of Section 4.8 as the basic interpreter.
␈↓ ↓H␈↓First,␈αthe␈αevaluation␈αof␈αa␈αconstant␈α␈↓αA␈↓␈αinvolves␈αthe␈αrecognition␈αthat␈αwe␈αhave␈αseen␈αa␈αconstant;␈αthat␈αis
␈↓ ↓H␈↓part␈α⊃of␈α⊂the␈α⊃control␈α⊃of␈α⊂the␈α⊃evaluator.␈α⊃ We␈α⊂evaluate␈α⊃that␈α⊃constant␈α⊂by␈α⊃␈↓αsend[denote[]]␈↓.␈α⊃The␈α⊂␈↓αdenote␈↓
␈↓ ↓H␈↓operation␈αis␈αstill␈αpart␈αof␈αthe␈αevaluator,␈α
but␈αthe␈α␈↓αsend␈↓␈αoperation␈αis␈αan␈αinstruction.␈α The␈α
execution␈αof
␈↓ ↓H␈↓␈↓αsend[A]␈↓␈α
performs␈α
the␈α
evaluation.␈αThe␈α
␈↓αrestore␈↓␈α
operation␈α
returns␈αthe␈α
evaluator␈α
to␈α
its␈α
previous␈αstate.
␈↓ ↓H␈↓We␈αmust␈αallow␈α
for␈αsome␈αstate-saving␈αin␈α
our␈αrepertoire␈αof␈αinstructions.␈α
The␈αevaluation␈αof␈αa␈α
function
␈↓ ↓H␈↓application,␈α
like␈α
␈↓αg[A]␈↓,␈α
involves␈α
the␈αevaluation␈α
of␈α
␈↓αA␈↓,␈α
the␈α
calling␈α
of␈α␈↓αg␈↓,␈α
and␈α
a␈α
means␈α
of␈α
returning␈αto
␈↓ ↓H␈↓the␈αcomputation␈αsurrounding␈α␈↓αg[A]␈↓.␈αFunction␈αcalls␈α
involve␈αseveral␈αthings:␈αwe␈αneed␈αspace␈α
to␈αcontain
␈↓ ↓H␈↓the␈α∩evaluated␈α∩arguments;␈α∩we␈α∩need␈α∩a␈α∩control␈α∩mechanism␈α∩to␈α∩describe␈α∩which␈α∩argument␈α∩is␈α∩being
␈↓ ↓H␈↓evaluated;␈α⊂we␈α⊃need␈α⊂to␈α⊃suspend␈α⊂a␈α⊂computation␈α⊃such␈α⊂that␈α⊃we␈α⊂can␈α⊂execute␈α⊃the␈α⊂function␈α⊃with␈α⊂the
␈↓ ↓H␈↓evaluated␈α⊃arguments;␈α⊃and␈α⊃we␈α⊃must␈α⊃be␈α⊃able␈α⊃to␈α⊃return␈α⊃to␈α⊃the␈α⊃suspended␈α⊃computation␈α⊃when␈α⊂the
␈↓ ↓H␈↓function has completed its task.
␈↓ ↓H␈↓␈↓↓288 Dynamic Structure␈↓ 56.2␈↓
␈↓ ↓H␈↓The␈α∞necessary␈α∞ingredients␈α∞are␈α∂already␈α∞present␈α∞in␈α∞␈↓αpeval␈↓;␈α∞we␈α∂need␈α∞only␈α∞extract␈α∞and␈α∂package␈α∞them.
␈↓ ↓H␈↓Clearly␈α␈↓αalloc_dest␈↓␈αis␈αinvolved␈αin␈αgetting␈αnew␈αspace␈αfor␈αthe␈αevaluated␈αarguments.␈αThere␈αis␈αa␈αsecond
␈↓ ↓H␈↓required␈α⊂activity␈α⊂since␈α⊃␈↓αalloc_dest␈↓␈α⊂always␈α⊂occurs␈α⊃in␈α⊂conjunction␈α⊂with␈α⊂a␈α⊃␈↓αsave␈↓␈α⊂of␈α⊂the␈α⊃current␈α⊂␈↓αdest␈↓.
␈↓ ↓H␈↓Therefore␈αwe␈αdefine␈αan␈αinstruction␈αnamed␈α␈↓αalloc␈↓␈αwhich␈αsaves␈αthe␈αcurrent␈αdestination␈α␈↓↓and␈↓␈αintitializes
␈↓ ↓H␈↓a new ␈↓αdest␈↓ block.
␈↓ ↓H␈↓Each␈α
slot␈α
of␈α
the␈α
destination␈α
block␈α
is␈α
filled␈α
by␈α
an␈α
appropriate␈α
␈↓αsend␈↓␈α
operation.␈α
Examination␈α
of␈α
the
␈↓ ↓H␈↓sub-states␈α∞of␈α∂␈↓αevalargs␈↓ (page 200)␈α∞reveals␈α∂another␈α∞machine␈α∂instruction:␈α∞␈↓αnext[]␈↓␈α∂is␈α∞used␈α∂to␈α∞increment
␈↓ ↓H␈↓the destination pointer.
␈↓ ↓H␈↓Finally,␈α∩after␈α∪all␈α∩the␈α∩arguments␈α∪are␈α∩evaluated,␈α∩we␈α∪must␈α∩make␈α∩the␈α∪destination␈α∩block␈α∪the␈α∩local
␈↓ ↓H␈↓environment,␈α∂and␈α∂call␈α∂the␈α∂function.␈α∂Thus␈α∂two␈α∂more␈α∂instructions:␈α∂␈↓αlink␈↓␈α∂will␈α∂attach␈α∂the␈α∞destination
␈↓ ↓H␈↓block␈αas␈αthe␈αlocal␈αenvironment,␈αand␈αand␈αrestore␈αthe␈αprevious␈αdest␈αblock;␈α␈↓αcall␈↓␈αwill␈αcall␈αthe␈αfunction,
␈↓ ↓H␈↓after␈αsaving␈αsufficient␈αcontrol␈αinformation␈αso␈αthat␈αwe␈αmay␈αreturn␈αafter␈αexecution␈αof␈αthe␈αfunction␈αis
␈↓ ↓H␈↓completed.
␈↓ ↓H␈↓For␈α∂example,␈α⊂consider␈α∂␈↓αf[g[A];h[B]]␈↓.␈α∂Assuming␈α⊂␈↓αf␈↓␈α∂and␈α∂␈↓αg␈↓␈α⊂are␈α∂λ-definitions␈α∂with␈α⊂formal␈α∂parameters
␈↓ ↓H␈↓␈↓α[x;y]␈↓ and ␈↓α[z]␈↓ respectively, and ␈↓αh␈↓ is a primitive, then an instruction sequence might be:
␈↓ ↓H␈↓αalloc[(X Y)]; alloc[(Z)]; send[A];
␈↓ ↓H␈↓α link[]; call[G]; next[];
␈↓ ↓H␈↓α alloc[(G1)]; send[B]; link[];
␈↓ ↓H␈↓α call[H]; link[]; call[F]
␈↓ ↓H␈↓There␈αare␈αtwo␈αclasses␈αof␈αinstructions␈αto␈αbreak␈αthe␈αsequential␈αflow␈αof␈αa␈αsequence␈αof␈αinstructions:␈αwe
␈↓ ↓H␈↓transfer␈αcontrol␈αwhen␈α
we␈αcall␈αor␈α
return␈αfrom␈αa␈αfunction;␈α
and␈αwe␈αtransfer␈α
control␈αwhen␈αwe␈αexecute␈α
a
␈↓ ↓H␈↓conditional expression.
␈↓ ↓H␈↓Examination␈α
of␈α∞␈↓αev2␈↓,␈α
␈↓αev5␈↓,␈α
and␈α∞␈↓αev6␈↓␈α
(page 199)␈α
reveals␈α∞some␈α
of␈α
the␈α∞details␈α
of␈α
a␈α∞function␈α
call-return
␈↓ ↓H␈↓sequence.␈α⊂ After␈α⊂saving␈α⊂the␈α⊂current␈α⊂environment,␈α⊂restoring␈α⊂the␈α⊂saved␈α⊂destination,␈α⊂and␈α⊂saving␈α⊂a
␈↓ ↓H␈↓continuation␈α∩point,␈α∩we␈α⊃passed␈α∩control␈α∩to␈α⊃the␈α∩body␈α∩of␈α⊃the␈α∩function.␈α∩ The␈α∩instruction␈α⊃sequence,
␈↓ ↓H␈↓representing␈α∂the␈α∂body␈α∂of␈α∂the␈α∞function,␈α∂will␈α∂be␈α∂terminated␈α∂by␈α∞a␈α∂call␈α∂on␈α∂␈↓αret␈↓.␈α∂This␈α∂instruction␈α∞will
␈↓ ↓H␈↓restore␈αthe␈αsaved␈αenvironment␈αand␈αreturn␈αcontrol␈αto␈αthe␈αinstruction␈αimmediately␈αafter␈αthe␈α␈↓αcall␈↓.␈αThe
␈↓ ↓H␈↓saved␈α
information␈αis␈α
governed␈αby␈α
the␈αvariable␈α
named␈α
␈↓αcontrol␈↓,␈αwith␈α
␈↓αcall␈↓␈αadding␈α
information,␈αand␈α
␈↓αret␈↓
␈↓ ↓H␈↓removing␈α_information.␈α_Before␈α_showing␈α_how␈α_instructions␈α_are␈α_executed␈α_and␈α_how␈α_␈↓αcontrol␈↓␈α_is
␈↓ ↓H␈↓manipulated, we will describe the primitives for conditional expressions.
␈↓ ↓H␈↓Examination␈α∀of␈α∃the␈α∀details␈α∀of␈α∃␈↓αevcond␈↓␈α∀and␈α∀its␈α∃associated␈α∀functions␈α∀(page 200),␈α∃exhibits␈α∀more
␈↓ ↓H␈↓instructions.␈α⊂We␈α⊂use␈α⊂the␈α⊂evaluator␈α⊂to␈α⊂evaluate␈α⊃a␈α⊂predicate;␈α⊂we␈α⊂then␈α⊂␈↓αreceive␈↓␈α⊂the␈α⊂result␈α⊃from␈α⊂the
␈↓ ↓H␈↓␈↓αdest␈↓-block.␈α
If␈α
that␈α
answer␈α
is␈α
true,␈α
we␈αevaluate␈α
one␈α
path;␈α
otherwise␈α
we␈α
evaluate␈α
another␈α
path.␈αWe
␈↓ ↓H␈↓see␈α
two␈α
instructions␈αhere:␈α
a␈α
test␈α
and␈αjump␈α
instruction,␈α
which␈α
we␈αshall␈α
call␈α
␈↓αreceive_test␈↓,␈α
which␈αtests
␈↓ ↓H␈↓the␈α
contents␈α
of␈α∞the␈α
current␈α
destination␈α∞slot␈α
and␈α
jumps␈α∞to␈α
one␈α
instruction␈α∞sequence␈α
if␈α
the␈α∞result␈α
is
␈↓ ↓H␈↓true,␈α∀and␈α∀jumps␈α∪to␈α∀(usually)␈α∀another␈α∀instruction␈α∪sequence␈α∀if␈α∀the␈α∪result␈α∀is␈α∀false.␈α∀The␈α∪second
␈↓ ↓H␈↓instruction␈α
is␈αa␈α
means␈α
of␈αjumping␈α
unconditionally␈αto␈α
a␈α
prescribed␈αinstruction␈α
sequence.␈αThis␈α
second
␈↓ ↓H␈↓instruction is named ␈↓αgoto␈↓.
␈↓ ↓H␈↓␈↓↓6.2␈↓ λkPrimitives for LISP 289␈↓
␈↓ ↓H␈↓For example, a conditional expression [p␈↓β1␈↓ → e␈↓β1␈↓; ...;p␈↓βn␈↓ → e␈↓βn␈↓] has a code sequence like:
␈↓ ↓H␈↓␈↓ ∧H␈↓ ∧x<instructions for p␈↓β1␈↓>
␈↓ ↓H␈↓␈↓ ∧H␈↓ ∧x[␈↓αreceive_test␈↓[] → <code for e␈↓β1␈↓>;␈↓αgoto[a0]␈↓]
␈↓ ↓H␈↓␈↓ ∧H␈↓ ∧x<instructions for p␈↓β2␈↓>
␈↓ ↓H␈↓␈↓ ∧H␈↓ ∧x ...
␈↓ ↓H␈↓␈↓ ∧H␈↓ ∧x<instructions for p␈↓βn␈↓>
␈↓ ↓H␈↓␈↓ ∧H␈↓ ∧x[␈↓αreceive_test␈↓[] → <code for e␈↓βn␈↓>;␈↓αgoto[a0]␈↓]
␈↓ ↓H␈↓␈↓ ∧H␈↓ ∧x␈↓αerr[NO_TRUE_COND_CLAUSE]
␈↓ ↓H␈↓α␈↓ ∧Ha0 . . .
␈↓ ↓H␈↓Whenever␈α∞␈↓αreceive_test␈↓␈α∞is␈α
true␈α∞we␈α∞execute␈α
a␈α∞sequence␈α∞of␈α
instructions␈α∞and␈α∞then␈α
transfer␈α∞out␈α∞of␈α
the
␈↓ ↓H␈↓conditional␈α⊂using␈α∂the␈α⊂␈↓αgoto␈↓.␈α∂ We␈α⊂could␈α⊂have␈α∂treated␈α⊂conditional␈α∂expressions␈α⊂like␈α⊂special␈α∂function
␈↓ ↓H␈↓calls,␈α
saving␈α∞␈↓αa0␈↓␈α
as␈α
the␈α∞continuation␈α
and␈α
restoring␈α∞it␈α
from␈α
␈↓αcontrol␈↓␈α∞instead␈α
of␈α
using␈α∞␈↓αgoto␈↓.␈α
However
␈↓ ↓H␈↓conditional expressions don't require that extra generality␈↓π 190␈↓.
␈↓ ↓H␈↓We␈α∂can␈α∞now␈α∂give␈α∞a␈α∂more␈α∞detailed␈α∂picture␈α∞of␈α∂a␈α∞device␈α∂which␈α∞can␈α∂execute␈α∞this␈α∂instruction␈α∂set.␈α∞A
␈↓ ↓H␈↓program␈α⊃will␈α⊃be␈α⊃represented␈α⊃as␈α⊃a␈α⊃sequence␈α⊃of␈α⊃instructions.␈α⊃Some␈α⊃of␈α⊃these␈α⊃instructions␈α∩may␈α⊃be
␈↓ ↓H␈↓prefaced␈α∪with␈α∪labels.␈α∪ These␈α∀labels␈α∪either␈α∪represent␈α∪function␈α∀names␈α∪or␈α∪names␈α∪used␈α∀within␈α∪a
␈↓ ↓H␈↓conditional␈α∞expression.␈α∞Given␈α∂a␈α∞sequence␈α∞of␈α∂instructions␈α∞named␈α∞␈↓αinst_seq␈↓,␈α∂we␈α∞expect␈α∞that␈α∂they␈α∞be
␈↓ ↓H␈↓executed␈α
in␈αsequence,␈α
unless␈α
some␈αtransfer␈α
of␈αcontrol␈α
occurs.␈α
For␈αexample,␈α
the␈α
following␈αprogram
␈↓ ↓H␈↓suffices for the execution of such instruction sequences:
␈↓ ↓H␈↓α␈↓ βHloop <= λ[[inst_seq]prog[[i_s;pc]
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬H␈↓ ¬hi_s ← inst_seq;
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬Hl␈↓ ¬h[null[i_s] → return[␈↓λ`␈↓αhalt]]
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬H␈↓ ¬hpc ← first[i_s];
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬H␈↓ ¬hi_s ← rest[i_s];
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬H␈↓ ¬h[is_label[pc] → NIL; ␈↓
t␈↓α → pc[]]
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬H␈↓ ¬hgo[l] ]]
␈↓ ↓H␈↓If␈α∩␈↓αloop␈↓␈α∩returns␈α∩␈↓αHALT␈↓,␈α∩then␈α∩the␈α∩result␈α∩of␈α∩our␈α∩computation␈α∩is␈α∩found␈α∩in␈α∩␈↓αdest␈↓.␈α∩ Labels␈α∩are␈α∩not
␈↓ ↓H␈↓executable␈α⊂instructions,␈α⊂and␈α⊂are␈α⊂therefore␈α⊂ignored.␈α⊂ The␈α⊂effect␈α⊂of␈α⊂␈↓αgoto␈↓␈α⊂is␈α⊂to␈α⊂replace␈α⊂the␈α⊂current
␈↓ ↓H␈↓instruction␈α⊃sequence␈α⊃with␈α⊃the␈α⊃sequence␈α⊃which␈α⊃begins␈α⊃immediately␈α⊃after␈α⊃the␈α⊃label␈α⊃which␈α∩is␈α⊃the
␈↓ ↓H␈↓argument␈α
to␈α∞the␈α
␈↓αgoto␈↓.␈α
The␈α∞effect␈α
of␈α
␈↓αcall-ret␈↓␈α∞is␈α
a␈α
bit␈α∞more␈α
complex.␈α
We␈α∞describe␈α
␈↓↓only␈↓␈α∞the␈α
control
␈↓ ↓H␈↓aspects␈α∪of␈α∪␈↓αcall␈↓,␈α∪leaving␈α∪the␈α∪other␈α∪details␈α∪until␈α∪later.␈α∪ Let␈α∪an␈α∪instance␈α∪␈↓αcall[fn]␈↓␈α∪be␈α∪the␈α∩current
␈↓ ↓H␈↓instruction;␈α
and␈α
let␈α
␈↓αis␈↓λ'␈↓␈α
be␈α
the␈α
current␈αinstruction␈α
sequence.␈α
Note␈α
that␈α
␈↓αis␈↓λ'␈↓␈α
is␈α
the␈αsequence␈α
immediately
␈↓ ↓H␈↓after␈αthe␈αcall.␈αWe␈αsave␈α␈↓αis␈↓λ'␈↓␈αon␈α␈↓αcontrol␈↓␈αby␈α␈↓αcontrol ← concat[is␈↓λ'␈↓α;control]␈↓;␈αthen␈αwe␈αset␈α␈↓αi_s␈↓␈αto␈αthe␈αsequence
␈↓ ↓H␈↓beginning at ␈↓αfn␈↓. Execution of ␈↓αgo[l]␈↓ sends us to label ␈↓αl␈↓ and we begin executing the body of ␈↓αfn␈↓.
␈↓ ↓H␈↓We leave ␈↓αfn␈↓ by executing ␈↓αret␈↓. This instruction performs
␈↓ ↓H␈↓␈↓ ∧F␈↓αi_s ← first[control]; control ← rest[control]␈↓;
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 190␈↓␈αOur␈αtreatment␈αof␈αconditionals␈αis␈αan␈αinstance␈αof␈α"open␈αcoding"␈αa␈αfunction␈αcall.␈αThat␈α
means␈αwe
␈↓ ↓H␈↓replace␈α
a␈α
possible␈α
␈↓αcall-ret␈↓␈α
with␈αthe␈α
"in-line"␈α
instruction␈α
sequence␈α
which␈αmakes␈α
up␈α
the␈α
body␈α
of␈αthe
␈↓ ↓H␈↓function.␈α
This␈α∞trick␈α
gives␈α
faster␈α∞execution,␈α
but␈α
takes␈α∞more␈α
space.␈α
We␈α∞will␈α
see␈α
another␈α∞instance␈α
of
␈↓ ↓H␈↓"open-coding" when we compile macros in Section 6.19.
␈↓ ↓H␈↓␈↓↓290 Dynamic Structure␈↓ 56.2␈↓
␈↓ ↓H␈↓and we are back at the instruction following the ␈↓αcall␈↓.
␈↓ ↓H␈↓Part␈αof␈αthe␈αexecution␈αof␈α␈↓αcall␈↓␈αand␈α␈↓αgoto␈↓␈αinvolves␈αlocating␈αthe␈αdesired␈αlabel.␈αSince␈αwe␈αhave␈αsaved␈αthe
␈↓ ↓H␈↓original␈α
instruction␈α
sequence␈α
we␈α
can␈αsearch␈α
that␈α
list␈α
for␈α
the␈αdesired␈α
label.␈α
We␈α
will␈α
see␈αmore␈α
effective
␈↓ ↓H␈↓ways for locating labels in Section 6.5.
␈↓ ↓H␈↓␈↓ ¬_␈↓↓6.3 ␈↓ SM␈↓↓: A Simple Machine␈↓
␈↓ ↓H␈↓This␈αsection␈αdescribes␈αa␈αsimple␈αmachine␈αwhich␈αhas␈αa␈αsufficient␈αinstruction␈αset␈αto␈αdescribe␈αthe␈αLISP
␈↓ ↓H␈↓primitives␈α
in␈α
terms␈α
of␈α
a␈α
more␈α
conventional␈α
machine␈↓π 191␈↓.␈α
Note␈α
that␈α
this␈α
machine␈α
is␈α
␈↓↓not␈↓␈α
necessary
␈↓ ↓H␈↓for␈αour␈αunderstanding␈αof␈α␈↓αeval␈↓.␈α␈↓αeval␈↓␈αis␈α
self-descriptive.␈αWe␈αneed␈αdescribe␈αa␈αmachine␈αonly␈α
to␈αdiscuss
␈↓ ↓H␈↓implementation␈α_and␈α_compilation.␈α→ This␈α_indeed,␈α_is␈α_an␈α→objection␈α_to␈α_describing␈α→meaning␈α_of
␈↓ ↓H␈↓programming␈α
languages␈αin␈α
terms␈αof␈α
a␈αcompiler:␈α
you␈α
must␈αthen␈α
understand␈α␈↓↓two␈↓␈α
things,␈αthe␈α
language
␈↓ ↓H␈↓␈↓↓and␈↓ a machine.
␈↓ ↓H␈↓The␈αsimple␈α
machine,␈α␈↓ SM␈↓,␈α
has␈αa␈α
similarity␈αto␈α
the␈αorganization␈α
of␈αthe␈α
PDP-10␈α[DEC 69].␈α
We␈αneed
␈↓ ↓H␈↓very␈α
few␈α
features␈α
to␈α
discuss␈α
the␈α
interesting␈α
facets␈α
of␈α
the␈α
implementation␈α
of␈α
our␈αprimitives.␈α
Certainly,
␈↓ ↓H␈↓if␈α∪we␈α∪were␈α∀to␈α∪undertake␈α∪a␈α∀real␈α∪implementation,␈α∪many␈α∀more␈α∪instructions␈α∪would␈α∀be␈α∪desirable.
␈↓ ↓H␈↓Similarly,␈α∂when␈α∂we␈α∂discuss␈α∂compilation␈α∂our␈α∂␈↓ SM␈↓␈α∂suffices,␈α∂but␈α∂if␈α∂we␈α∂wished␈α∂to␈α⊂perform␈α∂␈↓↓efficient␈↓
␈↓ ↓H␈↓compilation␈α
we␈α
would␈α
expect␈α
to␈α
have␈α
a␈αbetter␈α
instruction␈α
set.␈α
The␈α
point␈α
here␈α
is␈α
to␈αunderstand␈α
basic
␈↓ ↓H␈↓algorithms.␈α⊂When␈α⊃that␈α⊂is␈α⊃accomplished␈α⊂it␈α⊃is␈α⊂reasonable␈α⊃to␈α⊂examine␈α⊃problems␈α⊂of␈α⊃efficiency␈α⊂and
␈↓ ↓H␈↓details␈α∪of␈α∪implementation.␈α∪ We␈α∪address␈α∪some␈α∩of␈α∪the␈α∪techniques␈α∪available␈α∪for␈α∪optimization␈α∩of
␈↓ ↓H␈↓compiler code in later sections.
␈↓ ↓H␈↓␈↓ SM␈↓␈α∂has␈α∞a␈α∂conventional␈α∂addressable␈α∞main␈α∂memory,␈α∞including␈α∂registers,␈α∂␈↓αAC1,␈α∞AC2,␈α∂...,␈α∂ACn␈↓.␈α∞These
␈↓ ↓H␈↓registers,␈α∩called␈α∩␈↓↓accumulators␈↓,␈α∩can␈α∩either␈α∩be␈α∩used␈α∩as␈α∩special␈α∩pointer␈α∩registers␈α∩or␈α∪addressed␈α∩as
␈↓ ↓H␈↓memory␈α∞locations␈α
␈↓α0␈↓␈α∞through␈α∞␈↓αn␈↓.␈α
Each␈α∞memory␈α
location␈α∞is␈α∞assumed␈α
to␈α∞be␈α
large␈α∞enough␈α∞to␈α
contain
␈↓ ↓H␈↓two␈α∩addresses.␈α∩ For␈α∩sake␈α∩of␈α∪discussion,␈α∩assume␈α∩the␈α∩word␈α∩size␈α∪is␈α∩36␈α∩bits.␈α∩ The␈α∩mapping␈α∪of␈α∩a
␈↓ ↓H␈↓dotted-pair␈α
onto␈α
an␈α
␈↓ SM␈↓␈α
location␈αis␈α
straightforward:␈α
the␈α
␈↓αcar␈↓␈α
maps␈αto␈α
the␈α
left-half␈α
of␈α
the␈α
word;␈αthe
␈↓ ↓H␈↓␈↓αcdr␈↓,␈α
to␈α
the␈αright.␈α
The␈α
addressing␈α
space␈αfor␈α
dotted␈α
pairs␈αis␈α
therefore␈α
2␈↓π18␈↓.␈α
A␈αmemory␈α
area␈α
is␈αset␈α
aside
␈↓ ↓H␈↓to␈αcontain␈αsuch␈αdotted␈αpairs.␈α A␈αmemory␈αarea␈αis␈αalso␈αdedicated␈αto␈αfull-word␈αspace;␈αall␈αp-names␈αand
␈↓ ↓H␈↓numbers are stored there.
␈↓ ↓H␈↓Parts␈αof␈α␈↓ SM␈↓␈αmemory␈αcan␈αbe␈αdesignated␈αas␈αstacks.␈αEach␈αstack␈αis␈αa␈αcontiguous␈αarea␈αof␈αmemory,␈αand
␈↓ ↓H␈↓the␈αcurrent␈αtop␈αof␈αa␈αstack␈α
is␈αreferenced␈αby␈αone␈αof␈αthe␈α
registers,␈α␈↓αP1,␈α...,␈αPj␈↓;␈αthese␈αregisters␈α
are␈αcalled
␈↓ ↓H␈↓␈↓↓stack-pointers␈↓␈↓π 192␈↓.␈α∞ The␈α
stacks␈α∞will␈α∞be␈α
used␈α∞to␈α∞contain␈α
the␈α∞partial␈α∞results␈α
of␈α∞calculations␈α∞and␈α
will
␈↓ ↓H␈↓contain␈αthe␈α
information␈αnecessary␈α
to␈αimplement␈αthe␈α
return␈αfrom␈α
recursive␈αfunctions.␈α
In␈αmost␈αof␈α
the
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 191␈↓ See also [Deu 73].
␈↓ ↓H␈↓␈↓π 192␈↓ On the PDP-10 a stack pointer must be one of the ␈↓αAC␈↓ registers.
␈↓ ↓H␈↓␈↓↓6.3␈↓ λ@␈↓ SM␈↓↓: A Simple Machine 291␈↓
␈↓ ↓H␈↓compilers␈αwe␈α
discuss,␈αa␈α
single␈αstack␈α
suffices␈αfor␈α
saving␈αpartial␈α
computations,␈αenvironments,␈α
as␈αwell
␈↓ ↓H␈↓as control information. This single stack will be referred to by ␈↓αP␈↓.
␈↓ ↓H␈↓There␈α
are␈α∞only␈α
three␈α
classes␈α∞of␈α
instructions␈α
necessary␈α∞to␈α
describe␈α
our␈α∞implementation:␈α
instructions
␈↓ ↓H␈↓for constant generation, instructions for stack manipulation, and instructions for flow of control.
␈↓ ↓H␈↓The␈α∞control␈α∞instructions␈α∞and␈α∞some␈α∞of␈α∞the␈α∞stack␈α∞instructions␈α∞refer␈α∞to␈α∞the␈α∞program␈α∞counter␈α∞of␈α
␈↓ SM␈↓.
␈↓ ↓H␈↓This␈α∪counter␈α∪is␈α∪designated␈α∪as␈α∪␈↓ PC␈↓.␈α∪In␈α∀the␈α∪following,␈α∪␈↓αC␈↓␈α∪means␈α∪"contents␈α∪of...";␈α∪␈↓αac␈↓␈α∀means␈α∪any
␈↓ ↓H␈↓accumulator;␈α∩␈↓αloc␈↓␈α∩means␈α∩either␈α∩a␈α⊃memory␈α∩location␈α∩or␈α∩an␈α∩␈↓αac␈↓;␈α⊃and␈α∩␈↓αmem␈↓␈α∩is␈α∩reserved␈α∩for␈α⊃memory
␈↓ ↓H␈↓references␈↓π 193␈↓.
␈↓ ↓H␈↓Here are the instructions:
␈↓ ↓H␈↓αMOVEI ac const␈↓ βhC(ac) ← const
␈↓ ↓H␈↓αPUSH P ac␈↓ βhC(P) ← C(P)+1. ␈↓Increment stack pointer␈↓α
␈↓ ↓H␈↓α␈↓ βhC(C(P)) ← C(ac).␈↓ Copy contents of ␈↓αac␈↓ onto top of stack.␈↓α
␈↓ ↓H␈↓αPOP P ac␈↓ βhC(ac) ← C(C(P)). ␈↓Copy top of stack into ␈↓αac.
␈↓ ↓H␈↓α␈↓ βhC(P) ← C(P)-1. ␈↓Decrement stack pointer.␈↓α
␈↓ ↓H␈↓α␈↓The next two instructions are used in function call-return situations.␈↓α
␈↓ ↓H␈↓αPUSHJ P loc␈↓ βhC(P) ← C(P)+1. ␈↓Increment stack pointer␈↓α
␈↓ ↓H␈↓α␈↓ βhC(C(P)) ← C(␈↓ PC␈↓α).␈↓ Place address following the ␈↓αPUSHJ␈↓ in the stack.␈↓α
␈↓ ↓H␈↓α␈↓ βhC(␈↓ PC␈↓α) ← loc. ␈↓ change control to location ␈↓αloc␈↓.
␈↓ ↓H␈↓␈↓αPOPJ P␈↓ βhC(␈↓ PC␈↓α) ← C(C(P)). ␈↓Copy top of stack into ␈↓ PC␈↓.
␈↓ ↓H␈↓␈↓ βh␈↓αC(P) ← C(P)-1. ␈↓Decrement stack pointer.
␈↓ ↓H␈↓We␈α⊃have␈α⊂ignored␈α⊃some␈α⊂of␈α⊃the␈α⊂details␈α⊃of␈α⊂stack␈α⊃operations;␈α⊂each␈α⊃stack␈α⊂operations␈α⊃must␈α⊂consider
␈↓ ↓H␈↓boundary␈α∂conditions␈α∂on␈α∂the␈α∂storage␈α∂allocated␈α∞for␈α∂the␈α∂stack.␈α∂ Any␈α∂condition␈α∂which␈α∂would␈α∞violate
␈↓ ↓H␈↓these␈αbounds␈α
must␈αbe␈α
detectable.␈α If␈α
a␈αstack␈α
is␈αallocated␈α
in␈αa␈α
discontinuous␈αfashion ([Bis 74])␈αthen␈α
a
␈↓ ↓H␈↓storage␈αmanagement␈α
decision␈αmust␈α
be␈αmade;␈α
if␈αthe␈α
stacks␈αare␈α
of␈αfixed␈α
size,␈αthen␈α
an␈αerror␈α
must␈αbe
␈↓ ↓H␈↓signaled.
␈↓ ↓H␈↓αMOVE ac loc ␈↓ βhC(ac)␈α←␈αC(loc).␈↓␈αThis␈αis␈αan␈αinstruction␈αto␈αload␈αa␈αspecified␈α␈↓αac␈↓␈αwith␈αthe␈αcontents
␈↓ ↓H␈↓␈↓ βxof ␈↓αloc␈↓. Note ␈↓αloc␈↓ may be an ␈↓αac␈↓; e.g. ␈↓αMOVE AC␈↓β1␈↓α AC␈↓β2␈↓.
␈↓ ↓H␈↓αMOVEM ac loc ␈↓ βhC(loc)␈α$←␈α%C(ac).␈↓␈α$Copy␈α%contents␈α$of␈α$␈↓αac␈↓␈α%into␈α$␈↓αloc␈↓.␈α% For␈α$example,
␈↓ ↓H␈↓␈↓ βx␈↓αMOVEM AC␈↓β1␈↓α AC␈↓β2␈↓α = MOVE AC␈↓β2␈↓α AC␈↓β1␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 193␈↓ Again, in a real PDP-10 ␈↓αmem␈↓ can be an ␈↓αac␈↓.
␈↓ ↓H␈↓␈↓↓292 Dynamic Structure␈↓ 56.3␈↓
␈↓ ↓H␈↓αSUB ac loc␈↓ βhC(ac) ← C(ac) - C(loc).
␈↓ ↓H␈↓αJUMP mem␈↓ βhC(␈↓ PC␈↓α) ← mem. ␈↓Go to location ␈↓αmem␈↓.
␈↓ ↓H␈↓␈↓αJUMPF ac mem␈↓ βh␈↓↓if ␈↓αC(ac)=␈↓
f␈↓ ␈↓↓then␈↓α C(␈↓ PC␈↓α) ← mem;
␈↓ ↓H␈↓αJUMPT ac mem␈↓ βh␈↓↓if␈α∞␈↓αC(ac)␈↓≠␈↓α␈↓
f␈↓␈α∞␈↓↓then␈α∞␈↓αC(␈↓ PC␈↓α)␈α∞←␈α
mem.␈α∞ ␈↓Note␈α∞that␈α∞␈↓αJUMPT␈↓␈α∞implements␈α∞the␈α
coding
␈↓ ↓H␈↓␈↓ βxtrick of Section 5.5 which maps ␈↓
t␈↓ onto everything which is not false.
␈↓ ↓H␈↓These instructions are executed by a machine whose basic execution cycle is something like:
␈↓ ↓H␈↓α␈↓ β(␈↓ l:␈↓α␈↓ βXC(␈↓ IR␈↓α) ← C(C(␈↓ PC␈↓α))
␈↓ ↓H␈↓α␈↓ β(␈↓ βXC(␈↓ PC␈↓α) ← C(␈↓ PC␈↓α) + 1
␈↓ ↓H␈↓α␈↓ β(␈↓ βX ␈↓ execute ␈↓αC(␈↓ IR␈↓α)
␈↓ ↓H␈↓α␈↓ β(␈↓ βX␈↓ go to l
␈↓ ↓H␈↓The␈α␈↓ IR␈↓,␈αor␈α␈↓ Instruction␈αregister␈↓,␈αis␈αan␈αinternal␈αregister␈αused␈αto␈αhold␈α
the␈αinstruction
␈↓ ↓H␈↓we␈α
are␈αexecuting.␈α
Note␈α
that␈αthe␈α
␈↓ PC␈↓␈αregister␈α
is␈α
incremented␈α␈↓↓before␈↓␈α
execution␈αof␈α
the␈α
instruction.␈αIf
␈↓ ↓H␈↓we␈αincremented␈α
␈↓ PC␈↓␈α␈↓↓after␈↓␈α
the␈αexecution␈α
of␈αthe␈αinstruction,␈α
and␈αthe␈α
instruction␈αwere␈α
a␈αJUMP-type
␈↓ ↓H␈↓instruction, then the ␈↓ PC␈↓ would get a spurious incrementation.
␈↓ ↓H␈↓A␈αcritical␈αpart␈αof␈αLISP␈αevaluation␈αinvolves␈αprocedure␈αcalls␈αand␈αreturns.␈α Since␈αwe␈αexpect␈αto␈α
handle
␈↓ ↓H␈↓recursive␈αcalling␈α
sequences,␈αthe␈α␈↓αcall-ret␈↓␈α
pair␈α(page 288),␈α
represented␈αas␈α␈↓αCALL␈↓␈α
and␈α␈↓αRET␈↓,␈α
must␈αtake
␈↓ ↓H␈↓this␈αinto␈αaccount.␈αHowever,␈αthere␈αis␈αa␈αmore␈αfundamental␈αrequirement␈αof␈αthis␈αpair:␈αthey␈αmust␈αmake
␈↓ ↓H␈↓sure␈αthat,␈α
on␈αcompletion␈αof␈α
a␈α␈↓αCALL␈↓,␈α
the␈α␈↓αRET␈↓␈αcan␈α
return␈αto␈αthe␈α
instruction␈αwhich␈α
directly␈αfollows
␈↓ ↓H␈↓the␈α∂␈↓αCALL␈↓.␈α⊂ This␈α∂requirement␈α∂can␈α⊂be␈α∂accomplished␈α∂by␈α⊂a␈α∂less␈α∂comprehensive␈α⊂call,␈α∂say␈α⊂␈↓αJSR␈↓,␈α∂(for
␈↓ ↓H␈↓Jump␈α
SubRoutine),␈α
which␈α
stores␈α
the␈α
current␈α
value␈αof␈α
the␈α
␈↓ PC␈↓␈α
in␈α
a␈α
known␈α
location.␈α
Then␈αthe␈α
return,
␈↓ ↓H␈↓␈↓αJRTH␈↓,␈α(for␈αJump␈αTHrough),␈αneed␈αonly␈αpick␈αup␈αthat␈αsaved␈αvalue␈αand␈αrestore␈αit␈αinto␈αthe␈α␈↓ PC␈↓.␈αWe
␈↓ ↓H␈↓could␈α
implement␈α
this␈α
instruction␈α
on␈α
our␈α
machine.␈α∞ Recall␈α
that␈α
in␈α
the␈α
basic␈α
machine␈α
cycle␈α∞the␈α
␈↓ PC␈↓
␈↓ ↓H␈↓was␈αincremented␈α␈↓↓before␈↓␈αthe␈αexecution␈αof␈αthe␈αinstruction.␈αThus␈αif␈αwe␈αwere␈αabout␈αto␈αexecute␈αa␈α␈↓αJSR␈↓
␈↓ ↓H␈↓the␈α
␈↓ PC␈↓␈α
is␈αalready␈α
pointing␈α
at␈α
the␈αnext␈α
instruction;␈α
all␈α
we␈αneed␈α
to␈α
do␈α
is␈αsave␈α
the␈α
current␈α
␈↓ PC␈↓.␈α So
␈↓ ↓H␈↓let's assume that ␈↓αJSR F␈↓ stores the ␈↓ PC␈↓ in ␈↓αF␈↓ and begins execution in location ␈↓αF+1␈↓. Then:
␈↓ ↓H␈↓␈↓αJSR F␈↓ βhC(F) ← C(␈↓ PC␈↓α)␈↓. Save the ␈↓ PC␈↓ in ␈↓αF␈↓.
␈↓ ↓H␈↓␈↓ βh␈↓αC(␈↓ PC␈↓α) ← F + 1.␈↓ Jump to location represented by ␈↓αF + 1␈↓.
␈↓ ↓H␈↓␈↓αJRTH F␈↓␈↓ βh␈↓αC(␈↓ PC␈↓α) ← C(F).
␈↓ ↓H␈↓This␈α
pair␈αis␈α
indeed␈αhow␈α
several␈α
languages␈αperform␈α
their␈αcalling␈α
sequences.␈α It's␈α
fast␈α
and␈αefficient;
␈↓ ↓H␈↓however␈α
it␈α
is␈α
not␈α
sufficient␈αfor␈α
recursive␈α
control.␈α
If␈α
we␈α
always␈αstore␈α
in␈α
a␈α
␈↓↓fixed␈↓␈α
location,␈α
only␈αthe
␈↓ ↓H␈↓result␈αof␈αthe␈α␈↓↓last␈↓␈αstore␈αwould␈αbe␈αavailable␈αand␈αprevious␈αvalues␈αset␈αby␈αprior␈αrecursions␈αwould␈αhave
␈↓ ↓H␈↓been␈α⊂lost.␈α⊃ What␈α⊂we␈α⊃need␈α⊂is␈α⊃an␈α⊂implementation␈α⊂of␈α⊃the␈α⊂actions␈α⊃of␈α⊂␈↓αcontrol␈↓.␈α⊃ For␈α⊂purpose␈α⊃of␈α⊂our
␈↓ ↓H␈↓␈↓↓6.3␈↓ λ@␈↓ SM␈↓↓: A Simple Machine 293␈↓
␈↓ ↓H␈↓discussion␈αwe␈αcan␈αassume␈αthat␈α␈↓αcontrol␈↓␈αoperates␈αin␈αa␈αstack-like␈αfashion␈↓π 194␈↓.␈α What␈αthe␈α␈↓αCALL␈↓␈αwill␈αdo
␈↓ ↓H␈↓is␈α⊂␈↓↓push␈↓␈α⊂the␈α⊂current␈α⊂contents␈α⊂of␈α∂the␈α⊂␈↓ PC␈↓␈α⊂onto␈α⊂the␈α⊂control␈α⊂stack;␈α∂and␈α⊂␈↓αRET␈↓␈α⊂will␈α⊂pop␈α⊂off␈α⊂the␈α∂top
␈↓ ↓H␈↓element and put it into the ␈↓ PC␈↓ register␈↓π 195␈↓.
␈↓ ↓H␈↓The␈αbehavior␈αwe␈αhave␈αjust␈αdescribed␈αis␈αthat␈αattributed␈αto␈αthe␈α␈↓αPUSHJ-POPJ␈↓␈αpair␈αwhen␈αthey␈αare
␈↓ ↓H␈↓applied␈α
to␈αthe␈α
control␈α
stack.␈αWe␈α
have␈αseparated␈α
out␈α
the␈α␈↓αCALL-RET␈↓␈α
pair␈α
since␈αthe␈α
calling␈αprocess␈α
is
␈↓ ↓H␈↓not always as simple as ␈↓αPUSHJ-POPJ␈↓. Several things impinge on our decision:
␈↓ ↓H␈↓␈↓ α8␈↓↓1.␈↓␈αWe␈αwant␈αto␈αbe␈αable␈αto␈αsupply␈αdetailed␈αdebugging␈αinformation␈αto␈αthe␈αuser.␈αHow␈αthis␈αwill
␈↓ ↓H␈↓␈↓ α8be accomplished will be the topic of Section 6.23.
␈↓ ↓H␈↓␈↓ α8␈↓↓2.␈↓␈αWe␈αwant␈αto␈αbe␈αable␈αto␈αfreely␈αreplace␈αfunctions␈αwith␈αnew␈αdefinitions.␈αA␈α␈↓αPUSHJ␈↓␈αgoes␈αto
␈↓ ↓H␈↓␈↓ α8a particular sequence of instructions.
␈↓ ↓H␈↓␈↓ α8␈↓↓3.␈↓␈α∃We␈α∃want␈α∃to␈α∀be␈α∃able␈α∃to␈α∃intermix␈α∀compiled␈α∃and␈α∃interpreted␈α∃programs.␈α∀ Compiled
␈↓ ↓H␈↓␈↓ α8programs␈α⊂may␈α⊂call␈α⊂interpreted␈α⊂programs,␈α⊂and␈α⊂vice␈α⊂versa.␈α⊂Indeed␈α⊂we␈α⊂may␈α⊂even␈α⊂wish␈α∂to
␈↓ ↓H␈↓␈↓ α8replace an interpreted (compiled) definition with a compiled (interpreted) version.
␈↓ ↓H␈↓␈↓ α8␈↓↓4.␈↓␈αIn␈αdealing␈αwith␈αfunctional␈αarguments,␈αwe␈αmust␈αbe␈αable␈αto␈αtransfer␈αcontrol␈αto␈αa␈αfunction
␈↓ ↓H␈↓␈↓ α8variable. We cannot know where the ␈↓αPUSHJ␈↓ should transfer.
␈↓ ↓H␈↓When␈α∩an␈α∩interpreted␈α⊃function␈α∩calls␈α∩a␈α∩compiled␈α⊃(or␈α∩primitive)␈α∩function,␈α⊃␈↓αeval␈↓␈α∩will␈α∩look␈α∩for␈α⊃the
␈↓ ↓H␈↓indicator,␈α∞␈↓αSUBR␈↓;␈α∞then␈α∂retrieve␈α∞the␈α∞machine␈α∞address␈α∂of␈α∞the␈α∞code␈α∞and␈α∂enter␈α∞via␈α∞a␈α∂␈↓αPUSHJ␈↓.␈α∞That
␈↓ ↓H␈↓code␈αshould␈αexit␈α(back␈α
to␈α␈↓αeval␈↓)␈αvia␈αa␈α
␈↓αPOPJ␈↓,␈αafter␈αassuring␈αthat␈α
any␈αstacks␈αhave␈αbeen␈α
appropriately
␈↓ ↓H␈↓restored.
␈↓ ↓H␈↓Compiled␈α⊂functions␈α⊂call␈α⊃other␈α⊂functions␈α⊂via␈α⊃␈↓αCALL␈↓.␈α⊂ The␈α⊂␈↓αCALL␈↓␈α⊂must␈α⊃discover␈α⊂how␈α⊂to␈α⊃call␈α⊂the
␈↓ ↓H␈↓function:␈αis␈αit␈αa␈α␈↓αSUBR,␈αEXPR␈↓,␈αan␈α␈↓αFEXPR␈↓,␈αetc?␈α The␈αfunction␈αis␈αcalled␈αand␈αon␈αcompletion␈αcontrol
␈↓ ↓H␈↓is␈α⊃returned␈α⊃to␈α⊃the␈α⊂address␈α⊃immediately␈α⊃following␈α⊃the␈α⊃␈↓αCALL␈↓.␈α⊂ For␈α⊃example,␈α⊃␈↓α(CALL␈α⊃fn)␈↓␈α⊃can␈α⊂be
␈↓ ↓H␈↓implemented␈α∃as␈α∃␈↓α(PUSHJ␈α∃P␈α∃DECODE)␈↓,␈α⊗where␈α∃␈↓αP␈↓␈α∃represents␈α∃the␈α∃control␈α∃stack␈α⊗pointer,␈α∃and
␈↓ ↓H␈↓␈↓αDECODE␈↓␈α∂represents␈α∞a␈α∂routine␈α∞to␈α∂decode␈α∂the␈α∞actual␈α∂procedure␈α∞call.␈α∂Within␈α∞␈↓αdecode␈↓␈α∂we␈α∂know␈α∞that
␈↓ ↓H␈↓␈↓αC(C(P)-1)␈↓␈α∂is␈α∂the␈α∂actual␈α∂call␈α∂instruction;␈α∂␈↓αdecode␈↓␈α∂then␈α∂can␈α∂access␈α∂the␈α∂function␈α∂definition␈α∂associated
␈↓ ↓H␈↓with ␈↓αfn␈↓, set up the call, and then return via a ␈↓αPOPJ␈↓.
␈↓ ↓H␈↓Within␈α
any␈α
␈↓αCALL␈↓␈αor␈α
␈↓αPUSHJ␈↓␈α
we␈α
may␈αcall␈α
any␈α
function,␈α
including␈αthat␈α
function␈α
itself.␈α This␈α
brings
␈↓ ↓H␈↓us␈α
to␈αone␈α
of␈αthe␈α
most␈α
important␈αconventions␈α
for␈α␈↓↓any␈↓␈α
stack-like␈αcall-return␈α
sequence:␈α
Whatever␈αwe
␈↓ ↓H␈↓push␈α∂onto␈α∂a␈α∂stack␈α∂within␈α∂the␈α∂body␈α∂of␈α∂a␈α∂function␈α∂␈↓¬must␈↓␈α∂be␈α∂popped␈α∂off␈α∂before␈α∂we␈α∂exit␈α∂from␈α∂the
␈↓ ↓H␈↓function␈αbody.␈αThat␈αis,␈αthe␈α
state␈αof␈αany␈αstack␈αmust␈α
be␈αtransparent␈αto␈αany␈αcomputations␈αwhich␈α
occur
␈↓ ↓H␈↓within the function. This is called ␈↓↓stack synchronization␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 194␈↓␈α∪Unless␈α∪we␈α∪wish␈α∪to␈α∩consider␈α∪extensions␈α∪of␈α∪LISP,␈α∪a␈α∩stack␈α∪is␈α∪sufficient␈α∪for␈α∪LISP's␈α∩control
␈↓ ↓H␈↓environment.
␈↓ ↓H␈↓␈↓π 195␈↓␈α∞What␈α
will␈α∞be␈α
found␈α∞on␈α
the␈α∞control␈α
stack␈α∞is␈α
a␈α∞time-sequence␈α
of␈α∞those␈α
procedures␈α∞which␈α
have
␈↓ ↓H␈↓been␈α∀entered␈α∀but␈α∀have␈α∀not␈α∀yet␈α∪been␈α∀completed.␈α∀Such␈α∀information␈α∀is␈α∀exceptionally␈α∀useful␈α∪in
␈↓ ↓H␈↓debugging programs.
␈↓ ↓H␈↓␈↓↓294 Dynamic Structure␈↓ 56.3␈↓
␈↓ ↓H␈↓Usually␈α∞the␈α∞effect␈α
of␈α∞␈↓αRET␈↓␈α∞is␈α
identical␈α∞to␈α∞␈↓αPOPJ␈↓,␈α
however␈α∞it␈α∞is␈α
conceivable␈α∞that␈α∞we␈α∞might␈α
expect
␈↓ ↓H␈↓that␈αcomplex␈αreturns␈αrequire␈αspecial␈αcare.␈α The␈αbasic␈αidea␈αin␈αthis␈αdiscussion␈αis␈αthat␈αwe␈α
will␈αsupply
␈↓ ↓H␈↓two␈α
similar,␈αcompatible,␈α
but␈αnot␈α
identical␈αcall-return␈α
sequences;␈α␈↓αPUSHJ-POPJ␈↓␈α
is␈αfast␈α
and␈αsimple.
␈↓ ↓H␈↓The other, ␈↓αCALL-RET␈↓ is more general but more costly to invoke.
␈↓ ↓H␈↓In the next section we will reconcile LISP primitives with the instruction set supplied on ␈↓ SM␈↓.
␈↓ ↓H␈↓␈↓ ∧N␈↓↓6.4 Implementation of the Primitives␈↓
␈↓ ↓H␈↓As␈α
with␈α
any␈α
representation␈α
problem,␈α
several␈α
choices␈α
are␈α
available.␈α
We␈α
will␈α
begin␈α
our␈α
use␈α
of␈α␈↓ SM␈↓
␈↓ ↓H␈↓with␈α
a␈α
study␈α
of␈α
call-by-value␈α
function␈α
calls;␈α
later␈α
we␈α
will␈α
discuss␈α
other␈α
calling␈α
sequences.␈α
We␈α
will
␈↓ ↓H␈↓discuss␈α⊂two␈α⊂general␈α⊂implementation␈α⊂techniques.␈α⊂The␈α⊂first␈α⊂is␈α⊂applicable␈α⊂to␈α⊂machines␈α⊂without␈α∂the
␈↓ ↓H␈↓special ␈↓αAC␈↓'s of the ␈↓ SM␈↓.
␈↓ ↓H␈↓First,␈α
we␈α
will␈α
assume␈α
only␈α
that␈α
we␈α
are␈α
able␈αto␈α
simulate␈α
a␈α
stack.␈α
All␈α
the␈α
operations␈α
occur␈α
on␈αthe␈α
stack.
␈↓ ↓H␈↓Constants␈α⊃will␈α⊃be␈α⊃generated␈α⊃by␈α⊃pushing␈α⊃the␈α⊃representation␈α⊃on␈α⊃the␈α⊃top␈α⊃of␈α⊃the␈α⊃stack,␈α⊂essentially
␈↓ ↓H␈↓creating␈α
a␈α
␈↓αdest␈↓␈αblock.␈α
A␈α
function␈αcall,␈α
␈↓αf[t␈↓β1␈↓α; ... ;t␈↓βn␈↓α]␈↓,␈α
expects␈α
its␈αarguments␈α
as␈α
the␈αtop␈α
␈↓αn␈↓␈α
elements␈αof␈α
the
␈↓ ↓H␈↓stack,␈αwith␈αthe␈αvalue␈αof␈α␈↓αt␈↓βn␈↓␈αon␈αthe␈αtop␈αof␈αthe␈αstack,␈αand␈αthe␈αother␈αvalues␈αbelow.␈α As␈αthe␈αfunction␈αis
␈↓ ↓H␈↓called,␈αthe␈α␈↓αdest␈↓␈αblock␈αon␈αthe␈αtop␈αof␈αthe␈αstack␈αbecomes␈αthe␈αlocal␈αenvironment.␈αThe␈αfunction␈αreplaces
␈↓ ↓H␈↓the␈αtop␈α␈↓αn␈↓␈αelements␈αwith␈αthe␈αvalue␈αof␈αthe␈αfunction,␈αthus␈α␈↓αsend␈↓-ing␈αits␈αvalue␈αto␈αthe␈αdestination␈αof␈αthe
␈↓ ↓H␈↓caller.␈α
This␈α
model␈α
is␈α
a␈α
restricted␈α
subset␈α
of␈α
LISP,␈α
but␈α
it␈α
is␈α
a␈α
very␈α
useful␈α
subset.␈α
It␈α
will␈α
develop␈α
into␈α
a
␈↓ ↓H␈↓more␈α∪robust␈α∩example␈α∪as␈α∪the␈α∩chapter␈α∪progresses.␈α∩ The␈α∪technique␈α∪is␈α∩extendible␈α∪to␈α∪support␈α∩the
␈↓ ↓H␈↓implementation model we developed in Section 5.18.
␈↓ ↓H␈↓Here's an example of the implementation for the expression ␈↓αf[g[A];C;h[B]]␈↓:
␈↓ ↓H␈↓α␈↓ αX (PUSH P (QUOTE A))␈↓ πλ␈↓; make argument for call on ␈↓αg
␈↓ ↓H␈↓α␈↓ αX (CALL G)␈↓ πλ␈↓; call the function␈↓α
␈↓ ↓H␈↓α␈↓ αX (PUSH P (QUOTE C))␈↓ πλ␈↓; place second argument␈↓α
␈↓ ↓H␈↓α␈↓ αX (PUSH P (QUOTE B))
␈↓ ↓H␈↓α␈↓ αX (CALL H)␈↓ πλ␈↓; ␈↓αh␈↓ only uses (and removes) ␈↓αB
␈↓ ↓H␈↓α␈↓ αX (CALL F)␈↓ πλ␈↓; after the call, ␈↓αf[g[A];C;h[B]]␈↓ is
␈↓ ↓H␈↓␈↓ αX␈↓ πλ; on the top of the stack.
␈↓ ↓H␈↓Now␈αwe␈αwill␈αgive␈αimplementations␈αof␈αthe␈αLISP␈αprimitives␈αwhich␈αresult␈αin␈αreasonably␈αefficient␈αcode
␈↓ ↓H␈↓on␈αthe␈α␈↓ SM␈↓,␈αand␈αwhich␈αalso␈αreflect␈αseveral␈αpractices␈αapplied␈αin␈αcurrent␈αLISP␈αimplementations.␈α We
␈↓ ↓H␈↓will␈α
take␈αadvantage␈α
of␈αthe␈α
existence␈αof␈α
the␈αspecial␈α
␈↓αAC␈↓'s;␈αthe␈α
usual␈αhardware␈α
implementation␈αof␈α
such
␈↓ ↓H␈↓special registers allows access to their contents in less time than typical stack references␈↓π 196␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 196␈↓␈αThere␈αis␈αa␈αquestion␈αwhether␈αsuch␈αspecial␈αregisters␈αshould␈αbe␈αconsidered␈αgood␈αarchitecture␈αor␈αa
␈↓ ↓H␈↓trick.␈α
The␈α∞Burroughs␈α
6700-7700␈α∞uses␈α
special␈α∞hardware␈α
to␈α
decrease␈α∞access␈α
time␈α∞to␈α
the␈α∞initial␈α
stack
␈↓ ↓H␈↓segment.␈α
The␈α
PDP-10␈α
uses␈α∞special␈α
registers.␈α
One␈α
can␈α
argue␈α∞that␈α
such␈α
special␈α
tricks␈α
belong␈α∞in␈α
the
␈↓ ↓H␈↓␈↓↓6.4␈↓ π/Implementation of the Primitives 295␈↓
␈↓ ↓H␈↓Since␈α⊂the␈α⊂creating,␈α∂saving,␈α⊂and␈α⊂restoring␈α⊂of␈α∂destination␈α⊂blocks␈α⊂can␈α⊂be␈α∂expensive,␈α⊂we␈α⊂will␈α⊂try␈α∂to
␈↓ ↓H␈↓minimize␈α∂those␈α∂kinds␈α∂of␈α∂activities.␈α∂We␈α∂will␈α∞use␈α∂our␈α∂special␈α∂registers␈α∂␈↓αAC1␈↓,␈α∂through␈α∂␈↓αACn␈↓␈α∂to␈α∞build
␈↓ ↓H␈↓parameter␈α⊃lists␈α⊃and␈α⊃pass␈α⊃parameters.␈α⊃This␈α⊃entails␈α⊃several␈α⊃conventions.␈α⊃ We␈α⊃will␈α⊃try␈α⊃to␈α⊃use␈α⊃the
␈↓ ↓H␈↓accumulators␈α
as␈αthe␈α
destination␈α
block.␈α Our␈α
early␈α
compilers␈αwill␈α
be␈α
sufficiently␈αweak␈α
that␈αthis␈α
desire
␈↓ ↓H␈↓can be met. Later we will have to modify our stand slightly.
␈↓ ↓H␈↓The␈α
actual␈α
parameters␈αfor␈α
a␈α
function␈α
call,␈α␈↓αf[t␈↓β1␈↓α; ... ;t␈↓βn␈↓α]␈↓,␈α
will␈α
be␈α
developed␈αin␈α
␈↓αAC1␈↓␈α
through␈α
␈↓αACn␈↓.␈α In
␈↓ ↓H␈↓the␈α∂early␈α⊂compilers␈α∂we␈α⊂will␈α∂also␈α⊂pass␈α∂the␈α⊂evaluated␈α∂parameters␈α⊂to␈α∂the␈α⊂called␈α∂function␈α⊂using␈α∂the
␈↓ ↓H␈↓accumulators.␈αThus␈αvalues␈α
will␈αtend␈αto␈α
stay␈αin␈αthe␈α␈↓αAC␈↓'s␈α
unless␈αforced␈αout.␈α
They␈αcan␈αbe␈α
forced␈αout
␈↓ ↓H␈↓by␈α␈↓αalloc␈↓␈αsince␈αa␈αcall␈αto␈α␈↓αalloc␈↓␈αis␈αsupposed␈αto␈αsave␈αthe␈αcurrent␈α␈↓αdest␈↓.␈α The␈αinterplay␈αbetween␈α␈↓αnext␈↓,␈α␈↓αlink␈↓,
␈↓ ↓H␈↓and ␈↓αsend␈↓ requires care.
␈↓ ↓H␈↓We␈α
will␈α
assume␈α
that␈α
we␈α
are␈α
compiling␈αfor␈α
single␈α
valued␈α
functions,␈α
and␈α
therefore␈α
we␈α
must␈αresolve
␈↓ ↓H␈↓the␈αquestion␈αof␈αwhere␈αto␈αput␈αthe␈αvalue␈αof␈αa␈αfunction.␈α Again␈αconsider␈α␈↓αf[t␈↓β1␈↓α; ... ;t␈↓βn␈↓α]␈↓;␈αwe␈αmight␈αexpect
␈↓ ↓H␈↓that␈αeach␈α␈↓αt␈↓βi␈↓␈αbe␈αresponsible␈αfor␈α
placing␈αits␈αresult␈αin␈αthe␈αproper␈α
␈↓αACi␈↓.␈αIndeed␈αthat␈αis␈αthe␈αspirit␈α
of␈αthe
␈↓ ↓H␈↓␈↓αsend␈↓␈α∞operation;␈α∞it␈α∞knows␈α∞where␈α∞the␈α∂result␈α∞should␈α∞be␈α∞placed.␈α∞ This␈α∞strategy␈α∞requires␈α∂some␈α∞careful
␈↓ ↓H␈↓register allocation if it is to be carried out successfully. We will postpone this discussion for a while.
␈↓ ↓H␈↓There␈α∞is␈α∞a␈α∞simpler␈α∞solution␈α∞available:␈α∞a␈α∞function␈α∞always␈α∞returns␈α∞its␈α∞value␈α∞in␈α∞␈↓αAC1␈↓␈α∞and␈α∂leaves␈α∞the
␈↓ ↓H␈↓register allocation up to the calling function. There are at least two strategies here:
␈↓ ↓H␈↓↓␈↓ ¬xConvention 1
␈↓ ↓H␈↓We try to build the ␈↓αdest␈↓ block in the ␈↓αAC␈↓'s and also use the ␈↓αAC␈↓'s to pass parameters and values.
␈↓ ↓H␈↓␈↓ αhA␈α∞function␈α∞call,␈α∂␈↓αf[t␈↓β1␈↓α;␈α∞...;t␈↓βn␈↓α]␈↓,␈α∞expects␈α∞its␈α∂arguments␈α∞to␈α∞be␈α∞presented␈α∂in␈α∞␈↓αAC1␈↓
␈↓ ↓H␈↓␈↓ αhthrough␈α␈↓αACn␈↓.␈α
We␈αtry␈αto␈α
compute␈αthe␈αvalues␈α
of␈α␈↓αt␈↓βi␈↓␈αdirectly␈α
in␈α␈↓αACi␈↓.␈α
This␈αis
␈↓ ↓H␈↓␈↓ αheasy␈α
if␈α
␈↓αt␈↓βi␈↓␈α
is␈α
a␈α
constant;␈α
if␈α
␈↓αt␈↓βi␈↓␈α∞is␈α
a␈α
function␈α
call␈α
on␈α
␈↓αg␈↓,␈α
we␈α
save␈α∞␈↓αAC1␈↓␈α
through
␈↓ ↓H␈↓␈↓ αh␈↓αACi-1␈↓;␈α
set␈α
up␈αthe␈α
arguments␈α
to␈α␈↓αg␈↓;␈α
perform␈α
the␈αcall,␈α
returning␈α
the␈α
result␈αin
␈↓ ↓H␈↓␈↓ αh␈↓αAC1␈↓; move the result to ␈↓αACi␈↓; and restore the saved values of the ␈↓αt␈↓'s.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓hardware,␈α∞and␈α∞that␈α∂the␈α∞machine␈α∞presented␈α∞to␈α∂the␈α∞programmer␈α∞be␈α∞correspondingly␈α∂more␈α∞uniform
␈↓ ↓H␈↓[Dor 76].
␈↓ ↓H␈↓␈↓↓296 Dynamic Structure␈↓ 26.4␈↓
␈↓ ↓H␈↓↓␈↓ ¬wConvention 2
␈↓ ↓H␈↓We␈αtry␈α
to␈αbuild␈α
the␈α␈↓αdest␈↓␈α
block␈αin␈α
the␈αtop␈α
of␈αthe␈α
stack,␈αusing␈α
the␈α␈↓αAC␈↓'s␈α
for␈αpassing␈α
parameters␈αand
␈↓ ↓H␈↓returning values.
␈↓ ↓H␈↓␈↓ αhA␈α∞function␈α∞call,␈α∂␈↓αf[t␈↓β1␈↓α;␈α∞...;t␈↓βn␈↓α]␈↓,␈α∞expects␈α∞its␈α∂arguments␈α∞to␈α∞be␈α∞presented␈α∂in␈α∞␈↓αAC1␈↓
␈↓ ↓H␈↓␈↓ αhthrough␈α
␈↓αACn␈↓.␈α
As␈αwe␈α
compute␈α
each␈α
␈↓αt␈↓βi␈↓,␈αwe␈α
store␈α
the␈αresult␈α
on␈α
the␈α
stack␈α␈↓αP␈↓.
␈↓ ↓H␈↓␈↓ αhThus the execution sequence should be:
␈↓ ↓H␈↓␈↓ ∧Vcompute value of ␈↓αt␈↓β␈↓, push onto stack ␈↓αP␈↓.
␈↓ ↓H␈↓␈↓ ε. . . .
␈↓ ↓H␈↓␈↓ ∧Ecompute value of ␈↓αt␈↓βn-1␈↓, push onto stack ␈↓αP␈↓.
␈↓ ↓H␈↓␈↓ ∧dcompute value of ␈↓αt␈↓βn␈↓, move into ␈↓αACn␈↓.
␈↓ ↓H␈↓␈↓ αhAfter␈α
this␈αcomputation␈α
the␈αvalues,␈α
V␈↓βn-1␈↓,␈α
...,␈αV␈↓β1␈↓,␈α
of␈αthe␈α
arguments␈αare␈α
stored
␈↓ ↓H␈↓␈↓ αhfrom␈αtop␈αto␈αbottom␈αin␈α␈↓αP␈↓␈α
with␈αV␈↓βn␈↓␈αin␈α␈↓αACn␈↓.␈α Thus␈αto␈αcomplete␈α
the␈αfunction
␈↓ ↓H␈↓␈↓ αhinvocation,␈α∞we␈α∞need␈α∞only␈α∞pop␈α∞the␈α∞arguments␈α∞into␈α∞the␈α∞␈↓αAC␈↓'s␈α∞in␈α∞the␈α∞correct
␈↓ ↓H␈↓␈↓ αhorder␈α⊃and␈α⊃call␈α⊃␈↓αf␈↓.␈α⊂ We␈α⊃did␈α⊃not␈α⊃push␈α⊃V␈↓βn␈↓␈α⊂since␈α⊃we␈α⊃expected␈α⊃to␈α⊃pass␈α⊂the
␈↓ ↓H␈↓␈↓ αhparameters to ␈↓αf␈↓ in ␈↓αAC1␈↓ through ␈↓αACn␈↓.
␈↓ ↓H␈↓↓␈↓ αh␈↓ ¬HGeneral conventions
␈↓ ↓H␈↓␈↓ αhWhen␈α⊃a␈α⊃function␈α⊃completes␈α⊃evaluation,␈α⊃it␈α⊃is␈α⊃to␈α⊃place␈α⊃its␈α⊃value␈α⊃in␈α⊂␈↓αAC1␈↓.
␈↓ ↓H␈↓␈↓ αhNothing␈α∩can␈α∪be␈α∩assumed␈α∩about␈α∪the␈α∩contents␈α∩any␈α∪other␈α∩␈↓αAC␈↓.␈α∩If␈α∪an␈α∩␈↓αAC␈↓
␈↓ ↓H␈↓␈↓ αhcontains␈α∞information␈α∞we␈α∞need␈α∞then␈α∞it␈α
must␈α∞be␈α∞saved␈α∞on␈α∞the␈α∞stack␈α
␈↓↓before␈↓
␈↓ ↓H␈↓␈↓ αhcalling the function.
␈↓ ↓H␈↓␈↓ αhInstead␈α
of␈α
referring␈α
to␈α
␈↓αAC1,␈α
AC2,␈α
...,␈α
ACn␈↓␈α
we␈α
will␈α
simply␈α
use␈α
the␈αnumbers,␈α
␈↓α1,
␈↓ ↓H␈↓α␈↓ αh2, ..., n␈↓ in the instructions.
␈↓ ↓H␈↓We␈α∀give␈α∀an␈α∪example␈α∀of␈α∀both␈α∀conventions␈α∪for␈α∀the␈α∀expression␈α∪␈↓αf[g[A];C;h[B]]␈↓.␈α∀ We␈α∀use␈α∀a␈α∪list
␈↓ ↓H␈↓representation of the instructions and code sequences in preparation for future discussions.
␈↓ ↓H␈↓␈↓↓6.4␈↓ π/Implementation of the Primitives 297␈↓
␈↓ ↓H␈↓α␈↓ αX((MOVEI 1 (QUOTE A))␈↓ πλ␈↓; make argument for call on ␈↓αg
␈↓ ↓H␈↓α␈↓ αX (CALL G)␈↓ πλ␈↓; call the function␈↓α
␈↓ ↓H␈↓α␈↓ αX (MOVEI 2 (QUOTE C))␈↓ πλ␈↓; place second argument␈↓α
␈↓ ↓H␈↓α␈↓ αX (PUSH P 1)␈↓ πλ␈↓; but now we have to save the values␈↓α
␈↓ ↓H␈↓α␈↓ αX (PUSH P 2)␈↓ πλ␈↓; since we must compute ␈↓αh[B]
␈↓ ↓H␈↓α␈↓ αX (MOVEI 1 (QUOTE B))
␈↓ ↓H␈↓α␈↓ αX (CALL H)
␈↓ ↓H␈↓α␈↓ αX (MOVE 3 1)␈↓ πλ␈↓; move the result to ␈↓αAC3
␈↓ ↓H␈↓α␈↓ αX (POP P 2)␈↓ πλ␈↓; restore ␈↓αAC2␈↓ and ␈↓αAC1␈↓ in the correct order␈↓α
␈↓ ↓H␈↓α␈↓ αX (POP P 1)
␈↓ ↓H␈↓α␈↓ αX (CALL F) )
␈↓ ↓H␈↓↓␈↓ ¬xConvention 1
␈↓ ↓H␈↓α␈↓ αX((MOVEI 1 (QUOTE A))␈↓ πλ␈↓; make argument for call on ␈↓αg
␈↓ ↓H␈↓α␈↓ αX (CALL G)␈↓ πλ␈↓; call the function␈↓α
␈↓ ↓H␈↓α␈↓ αX (PUSH P 1)␈↓ πλ␈↓; save the value␈↓α
␈↓ ↓H␈↓α␈↓ αX (MOVEI 1 (QUOTE C))
␈↓ ↓H␈↓α␈↓ αX (PUSH P 1)␈↓ πλ␈↓; save the value␈↓α
␈↓ ↓H␈↓α␈↓ αX (MOVEI 1 (QUOTE B))
␈↓ ↓H␈↓α␈↓ αX (CALL H)
␈↓ ↓H␈↓α␈↓ αX (MOVE 3 1)␈↓ πλ␈↓; don't need to save the value␈↓α
␈↓ ↓H␈↓α␈↓ αX (POP P 2)␈↓ πλ␈↓; since this is the last argument.␈↓α
␈↓ ↓H␈↓α␈↓ αX (POP P 1)
␈↓ ↓H␈↓α␈↓ αX (CALL F) )
␈↓ ↓H␈↓↓␈↓ ¬wConvention 2
␈↓ ↓H␈↓Neither␈α∞compiling␈α∞convention␈α∞produces␈α
optimal␈α∞code␈α∞for␈α∞all␈α∞occasions.␈α
If␈α∞the␈α∞parameter␈α∞list␈α∞to␈α
a
␈↓ ↓H␈↓function␈α∞call␈α∞contains␈α∞only␈α∞constants,␈α∞then␈α∂the␈α∞first␈α∞convention␈α∞produces␈α∞better␈α∞code.␈α∞If␈α∂there␈α∞are
␈↓ ↓H␈↓many␈α
nested␈α
function␈αcalls␈α
then␈α
it␈α
may␈αproduce␈α
very␈α
bad␈α
code.␈αWe␈α
will␈α
worry␈α
more␈αabout␈α
efficiency
␈↓ ↓H␈↓after we develop the basic compiling algorithms.
␈↓ ↓H␈↓At␈α∀the␈α∃highest␈α∀level,␈α∀our␈α∃compiler␈α∀will␈α∃generate␈α∀code␈α∀for␈α∃the␈α∀␈↓αalloc-link-call-...␈↓␈α∃machine.␈α∀But
␈↓ ↓H␈↓frequently we will express the code in terms of one of our more traditional representations.
␈↓ ↓H␈↓The␈αoutput␈αfrom␈αthe␈αcompiler␈αis␈αto␈αbe␈αa␈αlist␈αof␈αinstructions,␈αin␈αthe␈αorder␈αwhich␈αwe␈αwould␈αexpect␈αto
␈↓ ↓H␈↓execute␈αthem.␈α
Each␈αinstruction␈α
is␈αa␈α
list:␈αan␈αoperation␈α
followed␈αby␈α
as␈αmany␈α
elements␈αas␈αare␈α
required
␈↓ ↓H␈↓by␈αthat␈αoperation.␈α We␈αcan␈αexecute␈αthe␈αcompiled␈αcode␈αby␈αsimulating␈αthe␈αactions␈αof␈αour␈αmachine␈αon
␈↓ ↓H␈↓each␈αelement␈αof␈αthe␈αsequence.␈α
However␈αit␈αis␈αmore␈αefficient␈α
to␈αtranslate␈αthis␈αcompiler␈αoutput␈α
further,
␈↓ ↓H␈↓producing␈αa␈αsequence␈αof␈αactual␈αmachine␈αinstructions,␈αplaced␈αin␈αmemory␈αand␈αsuitable␈αfor␈αexecution
␈↓ ↓H␈↓by␈α⊃the␈α⊃hardware␈α⊂processing␈α⊃unit.␈α⊃ We␈α⊃will␈α⊂allocate␈α⊃an␈α⊃area␈α⊃of␈α⊂memory␈α⊃which␈α⊃can␈α⊃receive␈α⊂the
␈↓ ↓H␈↓processed␈α∪compiler␈α∀output.␈α∪ This␈α∀area␈α∪is␈α∪usually␈α∀called␈α∪␈↓↓Binary␈α∀Program␈α∪Space␈↓␈α∀(BPS).␈α∪ The
␈↓ ↓H␈↓translation␈αprogram␈αwhich␈αtakes␈αthe␈αoutput␈αfrom␈αthe␈αcompiler␈αand␈αconverts␈αit␈αinto␈αactual␈αmachine
␈↓ ↓H␈↓instructions in BPS is called an assembler.
␈↓ ↓H␈↓␈↓↓298 Dynamic Structure␈↓ 46.5␈↓
␈↓ ↓H␈↓␈↓ ¬i␈↓↓6.5 Assemblers␈↓
␈↓ ↓H␈↓In␈α∃Section 6.2␈α∃we␈α∃gave␈α∀an␈α∃abstract␈α∃description␈α∃of␈α∀an␈α∃algorithm␈α∃for␈α∃executing␈α∃sequences␈α∀of
␈↓ ↓H␈↓instructions.␈α∩ In␈α∩this␈α∩section␈α∩we␈α∩discuss␈α⊃the␈α∩mechanism␈α∩for␈α∩getting␈α∩the␈α∩LISP␈α∩list,␈α⊃representing
␈↓ ↓H␈↓instructions,␈α
turned␈α
into␈α∞real␈α
instructions␈α
in␈α∞Binary␈α
Program␈α
Space.␈α∞ Part␈α
of␈α
the␈α∞process␈α
involves
␈↓ ↓H␈↓the␈αactual␈α
instructions;␈αbefore␈αa␈α
machine␈αcan␈αexecute␈α
an␈αinstruction␈αit␈α
must␈αbe␈αtransformed␈α
into␈αa
␈↓ ↓H␈↓numerical␈α∞code␈α
which␈α∞the␈α∞machine␈α
understands.␈α∞ Part␈α
of␈α∞the␈α∞process␈α
involves␈α∞establishing␈α∞a␈α
link
␈↓ ↓H␈↓between␈α⊂the␈α⊂code␈α⊂in␈α⊂memory␈α⊂and␈α⊂the␈α⊃LISP␈α⊂evaluator;␈α⊂when␈α⊂calling␈α⊂a␈α⊂routine␈α⊂which␈α⊃has␈α⊂been
␈↓ ↓H␈↓compiled,␈α∩the␈α∩evaluator␈α∩must␈α∩know␈α∩where␈α∩to␈α∩find␈α∩it.␈α∩Therefore,␈α∩part␈α∩of␈α∩the␈α∩process␈α∩involves
␈↓ ↓H␈↓mapping the the labels to locations in the machine.
␈↓ ↓H␈↓There␈α∃are␈α∃two␈α∃alternatives␈α∃available␈α∃to␈α∃solve␈α∃these␈α∃problems.␈α∃ We␈α∃might␈α⊗incorporate␈α∃these
␈↓ ↓H␈↓operations␈αinto␈α
the␈αcompiler.␈α
Then␈αthe␈α
output␈αfrom␈α
the␈αcompiler␈α
would␈αgo␈α
directly␈αto␈α
locations␈αin
␈↓ ↓H␈↓BPS.␈α∀ We␈α∪invoke␈α∀this␈α∪solution␈α∀in␈α∀Section 6.9␈α∪when␈α∀we␈α∪combine␈α∀compiling␈α∀and␈α∪interpreting.
␈↓ ↓H␈↓With␈α∪the␈α∪traditional␈α∩approach,␈α∪direct␈α∪loading␈α∪of␈α∩compiled␈α∪code␈α∪would␈α∪require␈α∩re-compilation
␈↓ ↓H␈↓whenever we wished to initiate a new LISP process which needed that function.
␈↓ ↓H␈↓The␈α∩alternative␈α∩is␈α∩to␈α∪compile␈α∩the␈α∩functions␈α∩onto␈α∩an␈α∪external␈α∩medium;␈α∩then␈α∩we␈α∩can␈α∪load␈α∩the
␈↓ ↓H␈↓compiled␈α
code␈αat␈α
any␈αtime.␈α
The␈α
premise␈αhere␈α
is␈αthat␈α
compilation␈α
is␈αan␈α
expensive␈αoperation␈α
relative
␈↓ ↓H␈↓to␈α⊂the␈α⊂cost␈α∂of␈α⊂loading␈α⊂compiled␈α⊂code.␈α∂ In␈α⊂this␈α⊂alternative␈α⊂scheme,␈α∂the␈α⊂tasks␈α⊂of␈α⊂loading,␈α∂locating
␈↓ ↓H␈↓labels,␈α⊂and␈α⊂linking␈α⊂the␈α⊃code␈α⊂with␈α⊂other␈α⊂modules,␈α⊂are␈α⊃all␈α⊂accomplished␈α⊂by␈α⊂a␈α⊂program␈α⊃called␈α⊂an
␈↓ ↓H␈↓␈↓↓assembler␈↓.␈αAfter␈αthe␈αassembler␈αhas␈αplaced␈αthe␈αdecoded␈αassembly␈αlanguage␈αin␈αBPS,␈αit␈αindicates␈αthat
␈↓ ↓H␈↓the value of the function name is the location of the assembled code.
␈↓ ↓H␈↓One␈α
of␈α
the␈α∞arguments␈α
to␈α
the␈α
assembler␈α∞should␈α
be␈α
the␈α
representation␈α∞of␈α
the␈α
program.␈α
One␈α∞of␈α
its
␈↓ ↓H␈↓arguments␈α
should␈α
also␈αdescribe␈α
where␈α
in␈α
BPS␈αwe␈α
wish␈α
the␈α
assembled␈αcode␈α
to␈α
be␈α
located.␈αWe␈α
should
␈↓ ↓H␈↓also␈α∩have␈α∩access␈α∪to␈α∩an␈α∩initial␈α∪symbol␈α∩table,␈α∩describing␈α∪the␈α∩pre-defined␈α∩symbol␈α∪names.␈α∩ These
␈↓ ↓H␈↓pre-defined␈α⊂names␈α∂might␈α⊂include␈α∂information␈α⊂about␈α∂the␈α⊂actual␈α∂machine␈α⊂locations␈α∂for␈α⊂the␈α∂utility
␈↓ ↓H␈↓functions,␈α
the␈α
values␈α
of␈α∞special␈α
stacks␈α
or␈α
registers␈α
which␈α∞the␈α
compiler␈α
uses␈α
internally,␈α
and␈α∞it␈α
must
␈↓ ↓H␈↓also␈αinclude␈αa␈αspecial␈αlist␈αgiving␈αa␈αcorrespondence␈αbetween␈αthe␈αnames␈αlike␈α␈↓αALLOC␈↓␈αor␈α␈↓αPUSHJ␈↓␈αand
␈↓ ↓H␈↓the actual numbers which the hardware uses in interpreting the instruction␈↓π 197␈↓.
␈↓ ↓H␈↓The␈α
assembler␈α
can␈α
go␈α
␈↓αrest␈↓-ing␈α
down␈α
the␈α
program␈α
list,␈α
looking␈α
up␈α
definitions␈α
and␈α
manufacturing␈α
the
␈↓ ↓H␈↓numerical␈αequivalent␈αof␈αeach␈αinstruction,␈αthen␈αdepositing␈αthat␈αnumber␈αin␈αthe␈αappropriate␈αmachine
␈↓ ↓H␈↓location.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 197␈↓␈α⊃A␈α⊃hardware␈α⊃machine␈α⊃is␈α⊃just␈α⊃another␈α⊂interpreter␈α⊃like␈α⊃␈↓αeval␈↓.␈α⊃It␈α⊃is␈α⊃usually␈α⊃not␈α⊃recursive,␈α⊂but
␈↓ ↓H␈↓performs more like ␈↓αloop␈↓ in the ␈↓αprog␈↓-evaluator.
␈↓ ↓H␈↓␈↓↓6.5␈↓ dAssemblers 299␈↓
␈↓ ↓H␈↓Below␈α⊃is␈α⊃a␈α∩low␈α⊃level␈α⊃representation␈α⊃of␈α∩a␈α⊃code␈α⊃sequence␈α⊃for␈α∩␈↓αf[g[A];h[B]]␈↓␈α⊃assuming␈α⊃that␈α⊃␈↓αh␈↓␈α∩is␈α⊃a
␈↓ ↓H␈↓primitive routine.
␈↓ ↓H␈↓It might be a list of the form:
␈↓ ↓H␈↓α␈↓ αX((MOVEI 1 (QUOTE A))␈↓ πλ␈↓; make argument for call on ␈↓αg
␈↓ ↓H␈↓α␈↓ αX (CALL G)␈↓ πλ␈↓; call the function␈↓α
␈↓ ↓H␈↓α␈↓ αX (PUSH P 1)␈↓ πλ␈↓; save the value␈↓α
␈↓ ↓H␈↓α␈↓ αX (MOVEI 1 (QUOTE B))
␈↓ ↓H␈↓α␈↓ αX (PUSHJ P H) ␈↓π 198␈↓α
␈↓ ↓H␈↓α␈↓ αX (MOVE 2 1)
␈↓ ↓H␈↓α␈↓ αX (POP P 1)
␈↓ ↓H␈↓α␈↓ αX (CALL F) )
␈↓ ↓H␈↓The␈α∪machine␈α∪representations␈α∪of␈α∪these␈α∪instructions␈α∪are␈α∪encodings␈α∪of␈α∪specific␈α∪fields␈α∪of␈α∪specific
␈↓ ↓H␈↓machine␈α∞locations␈α∞with␈α∞specific␈α∞numbers.␈α∞ For␈α∞example,␈α∞the␈α∞operation␈α∞␈↓αPUSH␈↓␈α∞is␈α∞represented␈α∞as␈α∞a
␈↓ ↓H␈↓certain␈α∞number,␈α∞called␈α∞its␈α
␈↓↓operation␈α∞code␈↓␈α∞or␈α∞␈↓↓op␈α
code␈↓,␈α∞and␈α∞which␈α∞will␈α
occupy␈α∞a␈α∞certain␈α∞area␈α∞of␈α
a
␈↓ ↓H␈↓machine␈α
word␈αso␈α
that␈αthe␈α
CPU␈α
can␈αinterpret␈α
it␈αas␈α
an␈α
instruction␈αto␈α
push␈αsomething␈α
onto␈α
a␈αstack.
␈↓ ↓H␈↓Other␈αfields␈αin␈αthe␈αinstruction␈αare␈αto␈αbe␈αinterpreted␈αas␈αreferences␈αto␈αstacks,␈αto␈αmemory␈αlocations,␈αto
␈↓ ↓H␈↓accumulators,␈αconstants␈αor␈αexternal␈αreferences␈αto␈αother␈αroutines.␈α The␈αpurpose␈αof␈αan␈αassembler␈αis␈αto
␈↓ ↓H␈↓translate these mnemonic instructions into machine instructions.
␈↓ ↓H␈↓Essentially␈α
all␈α∞that␈α
the␈α∞assembler␈α
need␈α
do␈α∞is␈α
search␈α∞symbol␈α
tables␈α
for␈α∞the␈α
opcodes,␈α∞for␈α
subroutine
␈↓ ↓H␈↓names,␈αfor␈αaccumulator␈αand␈αstack␈αnames,␈αand␈α
store␈αthe␈αresulting␈αvalues␈αin␈αthe␈αappropriate␈α
machine
␈↓ ↓H␈↓locations. Things are slightly more complex: later we must also ␈↓¬add␈↓ information to the tables.
␈↓ ↓H␈↓We␈α∂must␈α⊂exercise␈α∂a␈α∂bit␈α⊂of␈α∂care␈α∂in␈α⊂handling␈α∂␈↓αQUOTE␈↓d␈α∂expressions.␈α⊂ Assembling␈α∂a␈α⊂construct␈α∂like
␈↓ ↓H␈↓␈↓α(MOVEI␈α1␈α(QUOTE␈α(A␈αB␈αC)))␈↓␈αshould␈αhave␈αthe␈αeffect␈αof␈αconstructing␈αthe␈αlist␈α␈↓α(A␈αB␈αC)␈↓␈αin␈αfree␈αspace
␈↓ ↓H␈↓and␈α∂placing␈α∞an␈α∂instruction␈α∞in␈α∂memory␈α∞to␈α∂load␈α∞the␈α∂address␈α∞of␈α∂this␈α∞list␈α∂into␈α∞␈↓αAC1␈↓.␈α∂ What␈α∂we␈α∞must
␈↓ ↓H␈↓notice␈α∞is␈α∂that␈α∞this␈α∞list␈α∂␈↓α(A␈α∞B␈α∂C)␈↓␈α∞is␈α∞subject␈α∂to␈α∞garbage␈α∂collection␈α∞and,␈α∞if␈α∂left␈α∞unprotected,␈α∂could␈α∞be
␈↓ ↓H␈↓destroyed.␈α⊃ There␈α⊃are␈α⊃a␈α⊃couple␈α⊃of␈α⊃solutions.␈α⊃Perhaps␈α⊃the␈α⊃garbage␈α⊃collector␈α⊃could␈α⊃look␈α⊂through
␈↓ ↓H␈↓compiled␈αcode␈αfor␈αany␈αreferences␈αto␈αfree-space␈αor␈αfull-word-space;␈αor␈αwe␈αcould␈αmake␈αa␈αlist␈αof␈αall␈αof
␈↓ ↓H␈↓these␈α⊂constants␈α⊂and␈α⊃let␈α⊂the␈α⊂garbage␈α⊃collector␈α⊂mark␈α⊂the␈α⊂list.␈α⊃ Looking␈α⊂through␈α⊂compiled␈α⊃code␈α⊂is
␈↓ ↓H␈↓expensive;␈αkeeping␈αa␈α␈↓αQUOTE␈↓-list␈αis␈αa␈αreasonable␈α
compromise.␈αIt␈αis␈αa␈αcompromise␈αsince␈αthat␈α
strategy
␈↓ ↓H␈↓might retain unnecessary structures in case functions were redefined or recompiled.
␈↓ ↓H␈↓The␈α
assembler␈α
also␈α
needs␈α
to␈α
recognize␈α
that␈α
there␈α
are␈α
different␈α
instruction␈α
formats.␈α
That␈α∞is,␈α
some
␈↓ ↓H␈↓instructions␈αuse␈αan␈αopcode␈αand␈αa␈αmemory␈αreference:␈α␈↓α(JUMP L)␈↓;␈αsome␈αuse␈αan␈αopcode,␈αaccumulator,
␈↓ ↓H␈↓and␈αan␈αaddress:␈α␈↓α(PUSH P 1)␈↓;␈αand␈αsome␈αuse␈αa␈αLISP␈αconstruct:␈α␈↓α(MOVEI 1 (QUOTE␈αA))␈↓.␈α Therefore,
␈↓ ↓H␈↓the assembler has to have an initial symbol table of opcodes and stack numbers.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓α␈↓π 198␈↓α ␈↓Note that we use ␈↓αP␈↓; this assumes we use ␈↓αP␈↓ to save ␈↓↓both␈↓ value and control information.
␈↓ ↓H␈↓␈↓↓300 Dynamic Structure␈↓ 46.5␈↓
␈↓ ↓H␈↓Here is a sample op-code table with their machine equivalents:
␈↓ ↓H␈↓␈↓↓␈↓ ¬hsymbol␈↓ πλvalue␈↓α
␈↓ ↓H␈↓α␈↓ ¬hMOVE␈↓ πλ200
␈↓ ↓H␈↓α␈↓ ¬hMOVEI␈↓ πλ201
␈↓ ↓H␈↓α␈↓ ¬hSUB␈↓ πλ274
␈↓ ↓H␈↓α␈↓ ¬hJUMP␈↓ πλ254
␈↓ ↓H␈↓α␈↓ ¬hJUMPE␈↓ πλ322
␈↓ ↓H␈↓α␈↓ ¬hJUMPN␈↓ πλ326
␈↓ ↓H␈↓α␈↓ ¬hPUSH␈↓ πλ261
␈↓ ↓H␈↓α␈↓ ¬hPOP␈↓ πλ262
␈↓ ↓H␈↓α␈↓ ¬hPUSHJ␈↓ πλ260
␈↓ ↓H␈↓α␈↓ ¬hPOPJ␈↓ πλ263
␈↓ ↓H␈↓α␈↓ ¬hRET␈↓ πλ263
␈↓ ↓H␈↓α␈↓ ¬hCALL␈↓ πλ034
␈↓ ↓H␈↓α␈↓ ¬hP␈↓ πλ14
␈↓ ↓H␈↓And here's what the above example might resemble after being assembled:
␈↓"␈↓ ↓H␈↓
⊂αααπααπααααα⊃
␈↓"␈↓ ↓H␈↓
100 ~201~ 1~ 405~
␈↓"␈↓ ↓H␈↓
εαααβααβαααααλ
␈↓"␈↓ ↓H␈↓
~034~ ~ 1107~
␈↓"␈↓ ↓H␈↓
εαααβααβαααααλ
␈↓"␈↓ ↓H␈↓
~261~14~ 1~
␈↓"␈↓ ↓H␈↓
εαααβααβαααααλ
␈↓"␈↓ ↓H␈↓
~201~ 1~ 406~
␈↓"␈↓ ↓H␈↓
εαααβααβαααααλ
␈↓"␈↓ ↓H␈↓
~260~14~11121~
␈↓"␈↓ ↓H␈↓
εαααβααβαααααλ
␈↓"␈↓ ↓H␈↓
~200~ 2~ 1~
␈↓"␈↓ ↓H␈↓
εαααβααβαααααλ
␈↓"␈↓ ↓H␈↓
~262~14~ 1~
␈↓"␈↓ ↓H␈↓
εαααβααβαααααλ
␈↓"␈↓ ↓H␈↓
~034~ ~ 1051~
␈↓"␈↓ ↓H␈↓
%ααα∀αα∀ααααα$
␈↓ ↓H␈↓where␈α␈↓αA␈↓␈αis␈αlocated␈αat␈α␈↓
405␈↓;␈αthe␈αatom␈α␈↓αF␈↓␈αbegins␈αat␈α␈↓
1051␈↓,␈αand␈αthe␈αinstruction␈αsequence␈αfor␈α␈↓αh␈↓␈αbegins␈αat
␈↓ ↓H␈↓␈↓
11121␈↓, etc.
␈↓ ↓H␈↓␈↓ ∧e␈↓↓6.6 Compilers for Subsets of LISP␈↓
␈↓ ↓H␈↓We␈α⊂will␈α⊂examine␈α∂compilers␈α⊂for␈α⊂increasingly␈α∂complex␈α⊂subsets␈α⊂of␈α∂LISP␈α⊂beginning␈α⊂with␈α∂functions,
␈↓ ↓H␈↓composition␈α∞and␈α∞constant␈α∂arguments␈α∞and␈α∞ending␈α∂with␈α∞a␈α∞more␈α∂realistic␈α∞compiler␈α∞for␈α∂a␈α∞reasonable
␈↓ ↓H␈↓subset␈α⊂of␈α⊂pure␈α∂LISP.␈α⊂Though␈α⊂each␈α⊂subset␈α∂is␈α⊂a␈α⊂simple␈α⊂extension␈α∂of␈α⊂its␈α⊂predecessor,␈α⊂each␈α∂subset
␈↓ ↓H␈↓␈↓↓6.6␈↓ πZCompilers for Subsets of LISP 301␈↓
␈↓ ↓H␈↓introduces␈αa␈αnew␈αproblem␈αto␈αbe␈αsolved␈αby␈αthe␈αcompiling␈αalgorithm.␈α If␈αthe␈αcorresponding␈αevaluator
␈↓ ↓H␈↓(␈↓αtgmoaf␈↓,␈α␈↓αtgmoafr␈↓,␈αand␈αthe␈α
most␈αsimple␈α␈↓αeval␈↓)␈αis␈α
well␈αunderstood,␈αthen␈αthe␈α
necessary␈αsteps␈αto␈αbe␈α
added
␈↓ ↓H␈↓to the compiler are easy to make.
␈↓ ↓H␈↓The␈α∪first␈α∪compiler␈α∪will␈α∩handle␈α∪representations␈α∪of␈α∪that␈α∪subset␈α∩of␈α∪LISP␈α∪forms␈α∪defined␈α∪by␈α∩the
␈↓ ↓H␈↓following BNF equations:
␈↓ ↓H␈↓<form>␈↓ αh::= <constant> | <function>[<arg>; ...; <arg>]
␈↓ ↓H␈↓<arg>␈↓ αh::= <form>
␈↓ ↓H␈↓<constant>␈↓ αh::= <sexpr>
␈↓ ↓H␈↓<function>␈↓ αh::= <identifier>
␈↓ ↓H␈↓This␈αLISP␈αsubset␈αcorresponds␈α
closely␈αto␈αthat␈αof␈α
␈↓αtgmoaf␈↓,␈αhandling␈αonly␈αfunction␈αnames,␈α
composition,
␈↓ ↓H␈↓and␈α
constant␈α
arguments.␈α∞ In␈α
the␈α
interest␈α∞of␈α
readability␈α
and␈α
generality,␈α∞we␈α
will␈α
write␈α∞the␈α
functions
␈↓ ↓H␈↓using␈α∪constructors,␈α∀selectors,␈α∪and␈α∪recognizers␈α∀and␈α∪supply␈α∪the␈α∀necessary␈α∪bridge␈α∪to␈α∀our␈α∪specific
␈↓ ↓H␈↓representation by simple sub-functions.
␈↓ ↓H␈↓All␈α∂the␈α∞compilers␈α∂we␈α∞develop␈α∂will␈α∞be␈α∂derived␈α∞from␈α∂the␈α∞second␈α∂compiling␈α∞convention,␈α∂saving␈α∞the
␈↓ ↓H␈↓results␈αon␈αthe␈αtop␈αof␈αthe␈αstack.␈αOur␈αcompilers␈αwill␈αincorporate␈αsome␈αknowledge␈αof␈αthe␈α␈↓ SM␈↓␈α
machine,
␈↓ ↓H␈↓and␈α∂we␈α∞will␈α∂try␈α∞to␈α∂note␈α∞places␈α∂where␈α∞substantial␈α∂assumptions␈α∞about␈α∂machine␈α∞stucture␈α∂have␈α∞been
␈↓ ↓H␈↓made.
␈↓ ↓H␈↓␈↓αcompexp␈↓␈αexpects␈αto␈α
see␈αeither␈αa␈α
constant␈αor␈αa␈α
function␈αfollowed␈αby␈α
a␈αlist␈αof␈α
zero␈αor␈αmore␈α
arguments.
␈↓ ↓H␈↓The␈α
appearance␈αof␈α
a␈αconstant␈α
should␈αelicit␈α
the␈α
generation␈αof␈α
a␈αlist␈α
containing␈αa␈α
single␈αinstruction␈α
to
␈↓ ↓H␈↓␈↓αsend␈↓␈α⊃back␈α⊃the␈α⊃representation␈α⊂of␈α⊃that␈α⊃constant;␈α⊃␈↓αmksend[dest;exp]␈↓␈α⊃is␈α⊂a␈α⊃call␈α⊃on␈α⊃the␈α⊃constructor␈α⊂to
␈↓ ↓H␈↓generate␈αthat␈αinstruction.␈α Since␈αvalues␈αare␈αalways␈αfound␈αin␈α␈↓αAC1␈↓,␈αthat␈αshould␈αbe␈αthe␈αdestination␈αfor
␈↓ ↓H␈↓the ␈↓αsend␈↓. Since we are assuming the expression is a constant, the operation can be a ␈↓αMOVEI␈↓.
␈↓ ↓H␈↓If␈α⊂the␈α∂expression␈α⊂is␈α∂not␈α⊂a␈α∂constant,␈α⊂we␈α⊂can␈α∂assume␈α⊂it␈α∂is␈α⊂a␈α∂call-by-value␈α⊂application.␈α⊂We␈α∂should
␈↓ ↓H␈↓generate code to evaluate each argument, and follow that with code for a function call.
␈↓ ↓H␈↓αcompexp <=␈↓ αhλ[[exp]␈↓ βX[isconst[exp] → list[mksend[1;exp]];
␈↓ ↓H␈↓α␈↓ αh␈↓ βX ␈↓
t␈↓α →␈↓ ∧λλ[[z] compapply[␈↓ ¬hfunc[exp];
␈↓ ↓H␈↓α␈↓ αh␈↓ βX␈↓ ∧λ␈↓ ¬hcomplis[z];
␈↓ ↓H␈↓α␈↓ αh␈↓ βX␈↓ ∧λ␈↓ ¬hlength[z]]]
␈↓ ↓H␈↓α␈↓ αh␈↓ βX␈↓ ∧λ [arglist[exp]] ]]]␈↓
␈↓ ↓H␈↓␈↓↓302 Dynamic Structure␈↓ 56.6␈↓
␈↓ ↓H␈↓␈↓αcomplis␈↓␈α
gets␈α∞the␈α
representation␈α
of␈α∞the␈α
argument␈α
list;␈α∞it␈α
must␈α
generate␈α∞a␈α
code␈α
sequence␈α∞to␈α
evaluate
␈↓ ↓H␈↓each␈α⊃argument␈α⊃and␈α⊃increment␈α∩the␈α⊃destination.␈α⊃ After␈α⊃we␈α∩have␈α⊃compiled␈α⊃the␈α⊃last␈α∩argument␈α⊃we
␈↓ ↓H␈↓should␈αnot␈αincrement␈αthe␈αdestination.␈α Notice␈αthat␈αwe␈αhave␈αused␈α␈↓αappend␈↓␈αwith␈αthree␈αarguments;␈αthis
␈↓ ↓H␈↓could be justified by defining ␈↓αappend␈↓ as a macro (Section 3.12).
␈↓ ↓H␈↓αcomplis <= λ[[u]␈↓ β_[null[u] → ( );
␈↓ ↓H␈↓α␈↓ β_ null[rest[u]] → compexp[first[u]];
␈↓ ↓H␈↓α␈↓ β_ ␈↓
t␈↓α → append[␈↓ ∧Hcompexp[first[u]];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧Hlist[mkalloc[1]];
␈↓ ↓H␈↓α␈↓ β_␈↓ ∧Hcomplis[rest[u]]]] ]
␈↓ ↓H␈↓␈↓αcompapply␈↓␈α⊂has␈α⊂a␈α⊂simple␈α⊂task:␈α⊂it␈α⊂generates␈α⊂code␈α∂for␈α⊂allocation␈α⊂of␈α⊂the␈α⊂values;␈α⊂it␈α⊂takes␈α⊂the␈α⊂list␈α∂of
␈↓ ↓H␈↓instructions␈αmade␈αby␈α␈↓αcomplis␈↓␈αand␈αadds␈αinstructions␈αat␈αthe␈αend␈αof␈αthe␈αlist␈αto␈αgenerate␈αa␈αfunction␈αcall
␈↓ ↓H␈↓on ␈↓αfn␈↓. Here's ␈↓αcompapply␈↓:
␈↓ ↓H␈↓αcompapply <= λ[[fn;vals;n] append[␈↓ ¬_vals;
␈↓ ↓H␈↓α␈↓ ¬_mklink[n];
␈↓ ↓H␈↓α␈↓ ¬_list[mkcall[fn]]]]
␈↓ ↓H␈↓Finally, here are the constructors, selectors, and recognizers:
␈↓ ↓H␈↓␈↓↓Recognizer␈↓α
␈↓ ↓H␈↓αisconst <= λ[[x] or␈↓ β8[numberp[x];
␈↓ ↓H␈↓α␈↓ β8 eq[x;␈↓
t␈↓α];
␈↓ ↓H␈↓α␈↓ β8 eq[x;␈↓
f␈↓α];
␈↓ ↓H␈↓α␈↓ β8 and[not[atom[x]];eq[first[x];QUOTE]]]]
␈↓ ↓H␈↓α␈↓↓Selectors␈↓α
␈↓ ↓H␈↓αfunc <= λ[[x] first[x]]
␈↓ ↓H␈↓αarglist <= λ[[x] rest[x]]
␈↓ ↓H␈↓α␈↓↓Constructors␈↓α
␈↓ ↓H␈↓αmksend <= λ[[dest;val] list[MOVEI;dest;val]]
␈↓ ↓H␈↓αmkalloc <= λ[[dest] list[PUSH;P;dest]]
␈↓ ↓H␈↓αmkcall <= λ[[fn] list[CALL;fn]]
␈↓ ↓H␈↓αmklink <= λ[[n][eq[n;1] → ( ); ␈↓
t␈↓α → concat[mkmove[n;1];mklink1[sub1[n]]]]
␈↓ ↓H␈↓αmklink1 <= λ[[n][zerop[n] → ( ); ␈↓
t␈↓α → concat[mkpop[n];mklink1[sub1[n]]]];
␈↓ ↓H␈↓αmkpop <= λ[[n] list[POP;P;n]]
␈↓ ↓H␈↓αmkmove <= λ[[dest;val] list[MOVE;dest;val]]
␈↓ ↓H␈↓␈↓↓6.6␈↓ πZCompilers for Subsets of LISP 303␈↓
␈↓ ↓H␈↓Note␈α
that␈α␈↓αcompexp␈↓␈α
is␈αjust␈α
a␈αcomplex␈α
␈↓λr␈↓-mapping␈αwhose␈α
image␈αis␈α
a␈αsequence␈α
of␈α
machine␈αlanguage
␈↓ ↓H␈↓instructions.
␈↓ ↓H␈↓The␈α
code␈α
generated␈α
by␈α
this␈α
compiler␈α
is␈α
inefficient,␈α
but␈α
that␈α
is␈α
not␈α
our␈α
main␈α
concern.␈α
We␈α∞wish␈α
to
␈↓ ↓H␈↓establish␈α⊂an␈α⊂intuitive␈α⊂and␈α⊂correct␈α⊂compiler,␈α⊂then␈α⊂worry␈α⊂about␈α⊂efficiency.␈α⊂Premature␈α⊂concern␈α⊂for
␈↓ ↓H␈↓efficiency is folly; we must first establish a correct and clean algorithm.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I.␈α
Write␈α␈↓αcompexp␈↓␈α
to␈αgenerate␈α
code␈αfor␈α
␈↓↓option␈α
1␈↓␈αas␈α
discussed␈αon␈α
page 295.␈αCompare␈α
the␈αtwo␈α
versions
␈↓ ↓H␈↓of ␈↓αcompexp␈↓; now write a more abstract version which encompasses both as special cases.
␈↓ ↓H␈↓II.␈αWrite␈α␈↓αcompexp␈↓␈αand␈αassociated␈αfunctions␈αfor␈αa␈αstack-only␈αmachine␈αusing␈αthe␈αtechniques␈αoutlined
␈↓ ↓H␈↓on page 294.
␈↓ ↓H␈↓␈↓ ∧#␈↓↓6.7 Compilation of Conditional Expressions␈↓
␈↓ ↓H␈↓The␈α∂innovation␈α⊂which␈α∂occurred␈α⊂in␈α∂␈↓αtgmoafr␈↓␈α∂was␈α⊂the␈α∂introduction␈α⊂of␈α∂conditional␈α⊂expressions.␈α∂To
␈↓ ↓H␈↓describe conditional expressions, the BNF equations were augmented by:
␈↓ ↓H␈↓␈↓ β␈<form> ::= [<form> → <form> ; ... ;<form> → <form>]
␈↓ ↓H␈↓The␈αaddition␈αof␈αconditional␈αexpressions␈αwill␈αmean␈α
an␈αextra␈αpiece␈αof␈αcode␈αin␈α␈↓αcompexp␈↓␈α
to␈αrecognize
␈↓ ↓H␈↓␈↓αCOND␈↓␈α∀and␈α∀a␈α∀new␈α∀function␈α∀(analogous␈α∀to␈α∃␈↓αevcond␈↓␈α∀in␈α∀␈↓αtgmoafr␈↓)␈α∀to␈α∀generate␈α∀the␈α∀code␈α∃for␈α∀the
␈↓ ↓H␈↓␈↓αCOND␈↓-body␈↓π 199␈↓.␈α In␈αfact,␈αthe␈α
only␈αdifference␈αbetween␈α␈↓αevcond␈↓␈α
and␈αits␈αcounterpart␈αin␈α␈↓αcompexp␈↓,␈α
which
␈↓ ↓H␈↓we␈α
shall␈α
call␈α
␈↓αcomcond␈↓,␈α
is␈α
that␈α
␈↓αcomcond␈↓␈α
generates␈α
code␈α
which␈α
when␈α
executed␈α
will␈α
produce␈α
the␈α
same
␈↓ ↓H␈↓value as the value produced by ␈↓αevcond␈↓ operating on the given S-expression.
␈↓ ↓H␈↓The effect of ␈↓αcomcond␈↓ on a conditional of the form:
␈↓ ↓H␈↓␈↓ COND␈↓␈↓ βr␈↓α(COND␈↓ ␈↓α(␈↓
R␈↓∞(␈↓α p␈↓β1 ␈↓∞)␈↓α ␈↓
R␈↓∞(␈↓α e␈↓β1␈↓∞)␈↓α ) ... (␈↓
R␈↓∞(␈↓α p␈↓βn␈↓α ␈↓∞)␈↓α ␈↓
R␈↓∞(␈↓α e␈↓βn ␈↓∞)␈↓α))
␈↓ ↓H␈↓α␈↓ follows from the discussion of ␈↓αreceive_test␈↓ on page 289.
␈↓ ↓H␈↓First␈αgenerate␈αcode␈αfor␈αp␈↓β1␈↓;␈α
then␈αgenerate␈αa␈αtest␈αfor␈α
truth,␈αgoing␈αto␈αthe␈αcode␈α
for␈αe␈↓β1␈↓␈αif␈αtrue,␈αand␈α
going
␈↓ ↓H␈↓to␈αthe␈αcode␈αfor␈αp␈↓β2␈↓␈αif␈αnot␈αtrue.␈α The␈αcode␈αfor␈αe␈↓β1␈↓␈αmust␈αbe␈αfollowed␈αby␈αan␈αexit␈αfrom␈αthe␈αcode␈αfor␈αthe
␈↓ ↓H␈↓conditional, and we should generate an error condition to be executed in the case that p␈↓βn␈↓ is false.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 199␈↓␈αIf␈α
we␈αhad␈α
designed␈αthe␈αcompiler␈α
like␈αthe␈α
evaluators␈αin␈αSection 5.8␈α
we␈αwould␈α
need␈αonly␈αattach␈α
a
␈↓ ↓H␈↓compile-property to the atom ␈↓αCOND␈↓, and make the property-value ␈↓αCOMPCOND␈↓.
␈↓ ↓H␈↓␈↓↓304 Dynamic Structure␈↓ 56.7␈↓
␈↓ ↓H␈↓We represent the code as:
␈↓"␈↓ ↓H␈↓∂ ␈↓<code for p␈↓β1␈↓>␈↓∂
␈↓"␈↓ ↓H␈↓∂ /\
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ ␈↓∞G␈↓∂ ␈↓∞H␈↓∂
␈↓"␈↓ ↓H␈↓∂ T NIL
␈↓"␈↓ ↓H␈↓∂ / \
␈↓"␈↓ ↓H␈↓∂ ␈↓∞G␈↓∂ ␈↓∞H␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓<code for e␈↓β1␈↓>␈↓∂ ␈↓<code for p␈↓β2␈↓>␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞G␈↓∂ ␈↓∞GH␈↓∂
␈↓"␈↓ ↓H␈↓∂ / T NIL
␈↓"␈↓ ↓H␈↓∂ ␈↓∞G␈↓∂ ␈↓∞G␈↓∂ ␈↓∞H␈↓∂
␈↓"␈↓ ↓H␈↓∂ / ␈↓<code for e␈↓β2␈↓>␈↓∂ ␈↓<code for p␈↓β3␈↓>␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞G␈↓∂ / ␈↓∞GH␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ ␈↓∞G␈↓∂ ... ...
␈↓"␈↓ ↓H␈↓∂ \ / ␈↓∞G␈↓∂ ␈↓∞H␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ ␈↓∞G␈↓∂ T NIL
␈↓"␈↓ ↓H␈↓∂ \ / / \
␈↓"␈↓ ↓H␈↓∂ \ / ␈↓∞G␈↓∂ ␈↓∞H␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ ␈↓∞G␈↓∂ ␈↓<code for e␈↓βn␈↓>␈↓∂ ␈↓<code for error␈↓∂>
␈↓"␈↓ ↓H␈↓∂ \ / ␈↓∞G␈↓∂
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ ␈↓∞G␈↓∂
␈↓"␈↓ ↓H␈↓∂ ... /
␈↓"␈↓ ↓H␈↓∂ \ /
␈↓"␈↓ ↓H␈↓∂ ␈↓∞H␈↓∂ ␈↓∞G␈↓∂
␈↓ ↓H␈↓We␈α⊂will␈α⊃express␈α⊂␈↓αcomcond␈↓␈α⊂in␈α⊃terms␈α⊂of␈α⊂␈↓ SM␈↓␈α⊃primitives.␈α⊂ This␈α⊂requires␈α⊃the␈α⊂establishment␈α⊃of␈α⊂more
␈↓ ↓H␈↓conventions for our compiler, since we must implement ␈↓αreceive_test␈↓.
␈↓ ↓H␈↓↓␈↓ ¬ More Compiling Conventions
␈↓ ↓H␈↓␈↓ αhWe␈αmust␈αbe␈α
able␈αto␈αtest␈α
for␈α␈↓
t␈↓␈α(or␈α␈↓
f␈↓).␈α
Previous␈αconventions␈αimply␈α
that␈αthe
␈↓ ↓H␈↓␈↓ αhvalue␈αof␈αa␈αpredicate␈αwill␈αbe␈αfound␈αin␈α␈↓αAC1␈↓.␈α We␈αcan␈αtest␈αfor␈αthe␈αoccurrence
␈↓ ↓H␈↓␈↓ αhof␈α∩␈↓
t␈↓␈α∪or␈α∩␈↓
f␈↓␈α∩using␈α∪the␈α∩␈↓αJUMPT␈↓␈α∩or␈α∪␈↓αJUMPF␈↓␈α∩instruction␈α∪(see␈α∩Section 6.3)
␈↓ ↓H␈↓␈↓ αhrespectively␈↓π 200␈↓.
␈↓ ↓H␈↓We␈α⊃can␈α⊂implement␈α⊃␈↓αreceive_test␈↓␈α⊃using␈α⊂␈↓αJUMPT␈↓␈α⊃or␈α⊂␈↓αJUMPF␈↓,␈α⊃and␈α⊃we␈α⊂can␈α⊃implement␈α⊃␈↓αgoto␈↓␈α⊂using
␈↓ ↓H␈↓␈↓αJUMP␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 200␈↓␈αNote␈αthat␈α
this␈αimplementation␈αmaps␈αeverything␈α
not␈α␈↓
f␈↓␈αonto␈α
␈↓
t␈↓.␈αThus␈αany␈αvalue␈α
other
␈↓ ↓H␈↓than ␈↓
f␈↓ will be considered ␈↓
t␈↓. See Section 5.5.
␈↓ ↓H␈↓␈↓↓6.7␈↓ εWCompilation of Conditional Expressions 305␈↓
␈↓ ↓H␈↓Since␈α
our␈α
code␈α
is␈α
to␈αbe␈α
a␈α
␈↓↓sequence␈↓␈α
of␈α
instructions,␈αwe␈α
must␈α
linearize␈α
the␈α
graph-representation␈αof␈α
the
␈↓ ↓H␈↓generated␈α∞code.␈α∞ We␈α∞can␈α∞generate␈α∞a␈α∞sequence␈α∞representation␈α∞by␈α∞appropriately␈α∞interspersing␈α
labels
␈↓ ↓H␈↓and ␈↓αJUMP␈↓s between the blocks of instructions for the p␈↓βi␈↓'s and e␈↓βi␈↓'s. We will generate:
␈↓ ↓H␈↓␈↓ ¬_␈↓α(␈↓ ¬h␈↓<code for p␈↓β1␈↓>␈↓α
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ¬h(JUMPF 1 L1)␈↓
␈↓ ↓H␈↓␈↓ ¬_␈↓ ¬h<code for e␈↓β1␈↓>␈↓α
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ¬h(JUMP L0)
␈↓ ↓H␈↓α␈↓ ¬_L1␈↓ ¬h␈↓<code for p␈↓β2␈↓>␈↓α
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ¬h(JUMPF 1 L2)
␈↓ ↓H␈↓α␈↓ ¬_ ...
␈↓ ↓H␈↓α␈↓ ¬_Ln-1␈↓ ¬h␈↓<code for p␈↓βn␈↓>␈↓α
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ¬h(JUMPF 1 Ln)␈↓
␈↓ ↓H␈↓␈↓ ¬_␈↓ ¬h<code for e␈↓βn␈↓>␈↓α
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ¬h(JUMP L0)
␈↓ ↓H␈↓α␈↓ ¬_Ln␈↓ ¬h(JUMP ERROR)
␈↓ ↓H␈↓α␈↓ ¬_L0␈↓ ¬h )
␈↓ ↓H␈↓We␈α
need␈α
to␈α
construct␈α
the␈α
labels,␈α
␈↓αLi␈↓.␈α
These␈α
labels␈α
should␈α
be␈α
atomic␈α
and␈α
should␈α
be␈α∞distinct.␈α
LISP
␈↓ ↓H␈↓has␈α∂a␈α∞function,␈α∂␈↓αgensym␈↓,␈α∂which␈α∞can␈α∂be␈α∂used␈α∞for␈α∂this␈α∂task.␈α∞␈↓αgensym␈↓␈α∂is␈α∂a␈α∞function␈α∂of␈α∂no␈α∞arguments
␈↓ ↓H␈↓whose␈αvalue␈αis␈αa␈αdistinctive␈αsymbol␈αcalled␈αa␈αgenerated␈αsymbol,␈αor␈α"gensym".␈α Gensyms␈αare␈αnot␈αtrue
␈↓ ↓H␈↓atoms␈αsince␈αthey␈αare␈αnot␈αplaced␈αin␈αthe␈αobject␈αlist;␈αthey␈αare␈αusually␈αused␈αonly␈αfor␈αtheir␈αunique␈α
name.
␈↓ ↓H␈↓If␈α
it␈α
is␈α
desired␈α
to␈α
use␈αthem␈α
as␈α
atoms,␈α
they␈α
must␈α
be␈α
placed␈αon␈α
the␈α
object␈α
list␈α
using␈α
the␈αfunction␈α
␈↓αintern␈↓
␈↓ ↓H␈↓(page 259).␈α Gensyms␈αare␈α
distinct␈αfrom␈αeach␈αother␈α
and␈αwill␈αbe␈αdistinct␈α
from␈αall␈αother␈α
atoms␈αunless
␈↓ ↓H␈↓you read an atom with that pname␈↓π 201␈↓.
␈↓ ↓H␈↓We␈α⊂want␈α⊂to␈α⊂write␈α⊂a␈α⊂recursive␈α⊂version␈α∂of␈α⊂␈↓αcomcond␈↓;␈α⊂therefore␈α⊂we␈α⊂must␈α⊂determine␈α⊂what␈α⊂code␈α∂gets
␈↓ ↓H␈↓generated on each recursion and what code gets generated at the termination case.
␈↓ ↓H␈↓Looking at the example, we see that the block
␈↓ ↓H␈↓␈↓ β;␈↓α(␈↓<code for p␈↓βi␈↓> ␈↓α(JUMPF 1 Li) ␈↓<code for e␈↓βi␈↓> ␈↓α(JUMP L0) Li)␈↓
␈↓ ↓H␈↓is the natural segment for each recursion and that:
␈↓ ↓H␈↓␈↓ ¬7␈↓α((JUMP ERROR) L0)␈↓
␈↓ ↓H␈↓is␈α
to␈α
be␈αexpected␈α
for␈α
the␈α
termination␈αcase.␈α
Within␈α
each␈αblock␈α
we␈α
need␈α
a␈α"local"␈α
label,␈α
␈↓αLi␈↓;␈αand␈α
within
␈↓ ↓H␈↓each␈α∞block,␈α∂including␈α∞the␈α∂terminal␈α∞case,␈α∞we␈α∂refer␈α∞to␈α∂the␈α∞label␈α∞␈↓αL0␈↓␈α∂which␈α∞is␈α∂"global"␈α∞to␈α∂the␈α∞whole
␈↓ ↓H␈↓conditional. We can now add the recognizer for ␈↓αCOND␈↓ to ␈↓αcompexp␈↓ and construct ␈↓αcomcond␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 201␈↓␈α⊂In␈α⊂many␈α⊂versions␈α⊃of␈α⊂LISP,␈α⊂gensyms␈α⊂are␈α⊃of␈α⊂the␈α⊂form␈α⊂␈↓αGn␈↓␈α⊂where␈α⊃␈↓αn␈↓␈α⊂is␈α⊂a␈α⊂four␈α⊃digit␈α⊂number
␈↓ ↓H␈↓beginning␈αat␈α␈↓α0000␈↓.␈αThus␈αthe␈αfirst␈αcall␈αof␈α␈↓αgensym[␈α]␈↓␈αwould␈αgive␈α␈↓αG0000␈↓;␈αsucceeding␈αcalls␈αwould␈αgive
␈↓ ↓H␈↓␈↓αG0001, G0002␈↓, etc.
␈↓ ↓H␈↓␈↓↓306 Dynamic Structure␈↓ 56.7␈↓
␈↓ ↓H␈↓α␈↓Add the clause:
␈↓ ↓H␈↓α␈↓ ∧2iscond[exp] → comcond[args␈↓βc␈↓α[exp];gensym[ ]];
␈↓ ↓H␈↓to␈↓α compexp ␈↓where:
␈↓ ↓H␈↓αcomcond <= λ[[u;glob]␈↓ βh[null[u] → list[mkerror[ ];glob];
␈↓ ↓H␈↓α␈↓ βh ␈↓
t␈↓α → append[␈↓ ¬_comclause[first[u]; gensym[];glob];
␈↓ ↓H␈↓α␈↓ βh␈↓ ¬_comcond[rest[u]; glob] ]
␈↓ ↓H␈↓αcomclause <=λ[[p;loc;glob] append␈↓ ∧x[compexp[ante[p]];
␈↓ ↓H␈↓α␈↓ ∧x list[mkjumpf[loc]];
␈↓ ↓H␈↓α␈↓ ∧x compexp[conseq[p]];
␈↓ ↓H␈↓α␈↓ ∧x list[mkjump[glob];loc] ]]
␈↓ ↓H␈↓α␈↓↓Recognizer␈↓α
␈↓ ↓H␈↓αiscond <= λ[[x] eq[first[x]; COND]]
␈↓ ↓H␈↓α␈↓↓Selectors␈↓α
␈↓ ↓H␈↓αargs␈↓βc␈↓α <= λ[[x] rest[x]]
␈↓ ↓H␈↓αante <= λ[[c] first[c]]
␈↓ ↓H␈↓αconseq <= λ[[c] second[c]]␈↓π 202␈↓α
␈↓ ↓H␈↓α␈↓↓Constructors␈↓α
␈↓ ↓H␈↓αmkerror <= λ[[] (JUMP ERROR)]
␈↓ ↓H␈↓αmkjumpf <= λ[[l] list[JUMPF;1;l]]
␈↓ ↓H␈↓αmkjump <= λ[[l] list[JUMP;l]]
␈↓ ↓H␈↓The partially exposed recursive structure of ␈↓αcomcond␈↓ would show:
␈↓ ↓H␈↓␈↓ ∧`␈↓αcomcond[((␈↓p␈↓β1␈↓ e␈↓β1␈↓α) ...(␈↓p␈↓βn␈↓ e␈↓βn␈↓α));G0000]=
␈↓ ↓H␈↓α␈↓ ¬_(␈↓␈↓ ε_<code for p␈↓β1␈↓>␈↓α
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ε_(JUMPF 1 G0001)␈↓
␈↓ ↓H␈↓␈↓ ¬_␈↓ ε_<code for e␈↓β1␈↓>␈↓α
␈↓ ↓H␈↓α␈↓ ¬_␈↓ ε_(JUMP G0000)
␈↓ ↓H␈↓α␈↓ ¬_ G0001␈↓ ε_comcond[((␈↓p␈↓β2␈↓ e␈↓β2␈↓α) ...(␈↓p␈↓βn␈↓ e␈↓βn␈↓α)); G0000])
␈↓ ↓H␈↓We␈α
need␈α
to␈α
extend␈αour␈α
assembler␈α
to␈α
handle␈αthe␈α
generated␈α
labels␈α
and␈αjumps␈α
which␈α
appear␈α
in␈αthe
␈↓ ↓H␈↓conditional expression code.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓α␈↓π 202␈↓α␈α
␈↓This␈α
definition␈α
of␈α
␈↓αconseq␈↓␈α
does␈α
not␈α
allow␈α
extended␈α
conditional␈α
expressions.␈α
See␈α
problem␈α
II␈αon
␈↓ ↓H␈↓page 307.
␈↓ ↓H␈↓␈↓↓6.7␈↓ εWCompilation of Conditional Expressions 307␈↓
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Evaluate:␈↓ αx␈↓αcompexp[(COND␈↓ ∧x((EQ (QUOTE A)(QUOTE B))(QUOTE C))
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧x((NULL (QUOTE A))(QUOTE FOO)))]
␈↓ ↓H␈↓II. Extend ␈↓αcomcond␈↓ to handle extended conditional expressions.
␈↓ ↓H␈↓␈↓ ∧W␈↓↓6.8 One-pass Assemblers and Fixups␈↓
␈↓ ↓H␈↓The␈α∞compiled␈α∞instructions␈α∂for␈α∞conditional␈α∞expressions␈α∂adds␈α∞one␈α∞more␈α∂task␈α∞for␈α∞our␈α∂assembler:␈α∞we
␈↓ ↓H␈↓must␈α⊃handle␈α⊂the␈α⊃generated␈α⊂label␈α⊃constructs.␈α⊂ Recall␈α⊃the␈α⊂pattern␈α⊃for␈α⊂conditional␈α⊃expression␈α⊂code
␈↓ ↓H␈↓given␈αon␈αpage 305.␈α The␈α
code␈αsequence␈αconsists␈αof␈α
representations␈αof␈αinstructions␈αand␈α
labels.␈α The
␈↓ ↓H␈↓symbols,␈α
␈↓αL0,␈αL1,␈↓␈α
and␈α
␈↓αL2␈↓␈αin␈α
that␈α
example␈αare␈α
generated␈α
symbols,␈αrepresenting␈α
labels.␈α
Though␈αthe
␈↓ ↓H␈↓gensyms␈α⊂are␈α∂␈↓↓not␈↓␈α⊂true␈α∂atoms,␈α⊂they␈α∂␈↓↓will␈↓␈α⊂satisfy␈α∂the␈α⊂test␈α∂for␈α⊂␈↓αatom␈↓.␈α∂Therefore␈α⊂we␈α∂can␈α⊂recognize␈α∂an
␈↓ ↓H␈↓occurrence of a label using the predicate ␈↓αatom␈↓.
␈↓ ↓H␈↓If␈α
the␈αassembler␈α
recognizes␈αa␈α
label␈αdefinition,␈α
it␈αshould␈α
add␈αinformation␈α
to␈αa␈α
symbol␈α
table,␈αnoting
␈↓ ↓H␈↓that␈αthe␈α
label␈αhas␈α
been␈αseen␈α
and␈αthat␈α
it␈αis␈α
associated␈αwith␈α
a␈αspecific␈α
location␈αin␈α
memory.␈α Further
␈↓ ↓H␈↓references␈αto␈α
that␈αlabel␈αcan␈α
be␈αtranslated␈α
to␈αreferences␈αto␈α
the␈αassociated␈α
machine␈αlocation.␈α The␈α
only
␈↓ ↓H␈↓problem␈α
is␈αthat␈α
references␈αto␈α
labels␈αmay␈α
occur␈α
␈↓¬before␈↓␈αwe␈α
have␈αcome␈α
across␈αthe␈α
label␈α
definition␈αin
␈↓ ↓H␈↓the␈α∞program.␈α∂ Such␈α∞references␈α∂are␈α∞called␈α∂␈↓↓forward␈α∞references␈↓.␈α∂ For␈α∞example,␈α∂all␈α∞references␈α∂in␈α∞the
␈↓ ↓H␈↓␈↓αCOND␈↓-code are forward references␈↓π 203␈↓.There are two solutions to the forward reference problem:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α∂Make␈α∂two␈α∂passes␈α∂through␈α∂the␈α∂input␈α∂program.␈α∂ The␈α∂first␈α∂pass␈α∂builds␈α∂a␈α∂symbol␈α∂table␈α∂of␈α∞labels
␈↓ ↓H␈↓␈↓ ↓xdescribing␈α
where␈α
the␈α
labels␈α
will␈α
be␈α
assigned␈αin␈α
memory.␈α
A␈α
second␈α
pass␈α
uses␈α
this␈α
symbol␈αtable␈α
to
␈↓ ↓H␈↓␈↓ ↓xactually assemble the code into the machine.
␈↓ ↓H␈↓␈↓↓2.␈↓␈αThe␈α
other␈αsolution␈α
is␈αto␈α
make␈αone,␈αmore␈α
complex,␈αpass␈α
through␈αthe␈α
input.␈α Whenever␈α
we␈αcome
␈↓ ↓H␈↓␈↓ ↓xacross␈α⊃a␈α⊃forward␈α⊃reference␈α⊃we␈α⊃add␈α⊃information␈α⊃to␈α⊃the␈α⊃symbol␈α⊃table␈α⊃saying␈α⊃that␈α⊃a␈α⊂forward
␈↓ ↓H␈↓␈↓ ↓xreference␈α∂has␈α∂occurred␈α∂at␈α∂this␈α∂location.␈α∂ We␈α∂assemble␈α∂as␈α∂much␈α∂of␈α∂the␈α∂instruction␈α∂as␈α∂we␈α∂can.
␈↓ ↓H␈↓␈↓ ↓xWhen␈α∩a␈α∪label␈α∩definition␈α∪␈↓¬does␈↓␈α∩occur,␈α∪we␈α∩check␈α∩the␈α∪table␈α∩to␈α∪see␈α∩if␈α∪there␈α∩are␈α∪any␈α∩forward
␈↓ ↓H␈↓␈↓ ↓xreferences␈α∂pending␈α∂on␈α∂that␈α∂label.␈α∂ If␈α∂there␈α∞are,␈α∂we␈α∂␈↓¬fix-up␈↓␈α∂those␈α∂instructions␈α∂to␈α∂reference␈α∞the
␈↓ ↓H␈↓␈↓ ↓xlocation now assigned to the label.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 203␈↓␈α∂If␈α∂we␈α∂scan␈α∂the␈α∂instruction␈α∂sequence␈α∂in␈α∞the␈α∂order␈α∂in␈α∂which␈α∂the␈α∂code␈α∂would␈α∂be␈α∂executed,␈α∞we
␈↓ ↓H␈↓always␈α
refer␈α
to␈α
a␈α
label␈α
before␈α
we␈α
come␈αacross␈α
its␈α
definition.␈α
We␈α
could␈α
skirt␈α
the␈α
forward␈αreference
␈↓ ↓H␈↓problem␈αby␈αloading␈αthe␈αprogram␈αin␈αreverse␈αorder:␈αrather␈αthan␈αbeginning␈αwith␈αthe␈αfirst␈αinstruction
␈↓ ↓H␈↓and␈α⊂loading␈α⊂␈↓↓upward␈↓␈α⊂in␈α∂memory,␈α⊂we␈α⊂could␈α⊂begin␈α⊂with␈α∂the␈α⊂last␈α⊂instruction␈α⊂and␈α⊂load␈α∂downward.
␈↓ ↓H␈↓However,␈α∂this␈α∞would␈α∂only␈α∂be␈α∞a␈α∂temporary␈α∂expedient:␈α∞an␈α∂assembler␈α∂must␈α∞also␈α∂handle␈α∂␈↓αprog␈↓s.␈α∞The
␈↓ ↓H␈↓label structure of ␈↓αprog␈↓s is not restricted to such predictable behavior.
␈↓ ↓H␈↓␈↓↓308 Dynamic Structure␈↓ 46.8␈↓
␈↓ ↓H␈↓There␈α∀are␈α∀some␈α∀restrictions␈α∀which␈α∀are␈α∀imposed␈α∀on␈α∀one-pass␈α∀assemblers,␈α∀but␈α∃particularly␈α∀for
␈↓ ↓H␈↓assembling compiled code, one-pass assemblers are usually sufficient and are quite fast.
␈↓ ↓H␈↓There␈α∩are␈α⊃at␈α∩least␈α∩two␈α⊃ways␈α∩to␈α∩handle␈α⊃fixups␈α∩of␈α∩forward␈α⊃references.␈α∩ If␈α∩the␈α⊃fixups␈α∩are␈α∩of␈α⊃a
␈↓ ↓H␈↓particularly␈α
simple␈α∞nature,␈α
say␈α∞only␈α
requiring␈α∞fixups␈α
to␈α∞the␈α
address-part␈α∞of␈α
a␈α∞word,␈α
then␈α∞we␈α
may
␈↓ ↓H␈↓link those pending forward references together, chaining them on their, as yet, un-fixed-up field.
␈↓"␈↓ ↓H␈↓
⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
~ ~ ≤' ~←α⊃
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ ~
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ↑
␈↓"␈↓ ↓H␈↓
~ ~ ~ ~
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ #ααβαα$
␈↓"␈↓ ↓H␈↓
~ ~ ~←α⊃
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ ↑
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ ~
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ↑
␈↓"␈↓ ↓H␈↓
~ ~ #ααβαα$
␈↓"␈↓ ↓H␈↓
~ ~ ~←α⊃
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ ↑
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ ↑
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ ~
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ ↑
␈↓"␈↓ ↓H␈↓
pointer from αααααα→ ~ ~ #ααβαα$
␈↓"␈↓ ↓H␈↓
entry in object list %ααααα∀ααααα$
␈↓ ↓H␈↓↓␈↓ ¬+A Simple Fixup Scheme
␈↓ ↓H␈↓Each␈α
time␈α
a␈αforward␈α
reference␈α
is␈α
seen␈αit␈α
is␈α
added␈α
to␈αthe␈α
linked␈α
list;␈α
when␈αthe␈α
label␈α
is␈αfinally␈α
defined
␈↓ ↓H␈↓and␈αgiven␈αan␈αaddress␈αin␈αmemory,␈αthen␈αthe␈αaddress␈αreplaces␈αeach␈αreference␈αlink.␈αNo␈αextra␈αstorage␈α
is
␈↓ ↓H␈↓used since the linked list is stored in the partially assembled code.
␈↓ ↓H␈↓Another␈αsolution,␈αwhich␈αis␈αpotentially␈αmore␈αgeneral␈α(that␈αis,␈αit␈αcould␈αhandle␈α
arbitrary␈αpartial-word
␈↓ ↓H␈↓fixups) is to store the information about each fixup in the symbol table under each label.
␈↓ ↓H␈↓␈↓↓6.8␈↓ π?One-pass Assemblers and Fixups 309␈↓
␈↓"␈↓ ↓H␈↓
from object list entry
␈↓"␈↓ ↓H␈↓
~ ⊂αααααπααα⊃ ⊂αααααπααα⊃ ⊂αααααπααα⊃
␈↓"␈↓ ↓H␈↓
%αα→~ # ~ #αβαα→~ # ~ #αβαα→~ # ~ . . .
␈↓"␈↓ ↓H␈↓
⊂ααααααααααα⊃ %ααβαα∀ααα$ %ααβαα∀ααα$ %ααβαα∀ααα$
␈↓"␈↓ ↓H␈↓
~ ~ ↓ ↓ ↓
␈↓"␈↓ ↓H␈↓
εαααααααααααλ ~ ~ ~
␈↓"␈↓ ↓H␈↓
~ ~←ααααα$ ~ ~
␈↓"␈↓ ↓H␈↓
εαααααααααααλ ↓ ↓
␈↓"␈↓ ↓H␈↓
~ ~ ~ ~
␈↓"␈↓ ↓H␈↓
εαααααααααααλ ~ ~
␈↓"␈↓ ↓H␈↓
~ ~←ααααααα←ααααααα←ααα$ ~
␈↓"␈↓ ↓H␈↓
εαααααααααααλ ↓
␈↓"␈↓ ↓H␈↓
~ ~←ααααααα←ααααααα←ααααααααα←ααααααα$
␈↓"␈↓ ↓H␈↓
εαααααααααααλ
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
ε . . . λ
␈↓ ↓H␈↓↓␈↓ ¬4Another Fixup Scheme
␈↓ ↓H␈↓In␈α
this␈α
scheme␈αwe␈α
could␈α
store␈α
additional␈αinformation␈α
with␈α
each␈α
link␈αin␈α
the␈α
list.␈α
That␈αinformation
␈↓ ↓H␈↓could tell the fixup routine how to modify the designated location.
␈↓ ↓H␈↓Both␈α
methods␈α
are␈α
useful.␈α
Both␈α
have␈α
been␈α
used␈α
extensively␈α
in␈α
assemblers␈α
and␈α
compilers.␈α
We␈α
now
␈↓ ↓H␈↓sketch␈α∩a␈α∩simple␈α∩one-pass␈α∩assembler,␈α∩named␈α∩␈↓αassemble␈↓.␈α∩ To␈α∩describe␈α∩␈↓αassemble␈↓,␈α∩we␈α∩will␈α∪need␈α∩two
␈↓ ↓H␈↓functions:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α∩␈↓αdeposit␈↓␈↓α[x;y]␈↓:␈α∪␈↓αx␈↓␈α∩represents␈α∪a␈α∩machine␈α∪address;␈α∩␈↓αy␈↓␈α∪is␈α∩a␈α∪list,␈α∩representing␈α∪the␈α∩instruction␈α∪to␈α∩be
␈↓ ↓H␈↓␈↓ β_deposited.␈α⊃␈↓αy␈↓␈α⊃could␈α⊃be␈α⊃a␈α⊃list␈α⊃of␈α⊃elements:␈α⊃␈↓α(␈↓opcode,␈α⊃accumulator␈α⊃number,␈α⊃memory
␈↓ ↓H␈↓␈↓ β_address␈↓α)␈↓ The value of ␈↓αdeposit␈↓ is the value of ␈↓αy␈↓.
␈↓ ↓H␈↓␈↓↓2.␈↓␈α
␈↓αexamine␈↓␈↓α[x]␈↓:␈α
␈↓αx␈↓␈α
represents␈α
a␈α
machine␈α
address.␈α
The␈αvalue␈α
of␈α
␈↓αexamine␈↓␈α
is␈α
the␈α
contents␈α
of␈α
location␈α␈↓αx␈↓␈α
in
␈↓ ↓H␈↓␈↓ βλthe form of a list as specified above.
␈↓ ↓H␈↓We␈αcan␈αnow␈αuse␈αour␈αfixup␈αmechanism,␈αcombined␈αwith␈α␈↓αexamine␈↓,␈α␈↓αdeposit␈↓,␈αand␈α␈↓αputprop␈↓␈αand␈α␈↓αremprop␈↓
␈↓ ↓H␈↓from␈α
page 242␈αto␈α
write␈α
the␈αparts␈α
of␈α
the␈αassembler␈α
which␈α
worry␈αabout␈α
forward␈α
references␈αand␈α
labels.
␈↓ ↓H␈↓We␈α
will␈α
use␈αthe␈α
second␈α
fixup␈αscheme.␈α
If␈α
the␈α
label␈αhas␈α
been␈α
assigned␈αa␈α
location␈α
then␈α
the␈αproperty
␈↓ ↓H␈↓list␈αof␈α
the␈αlabel␈α
will␈αcontain␈αthe␈α
indicator␈α␈↓αSYM␈↓␈α
and␈αan␈αassociated␈α
value␈αrepresenting␈α
the␈αassigned
␈↓ ↓H␈↓location.␈α If␈αthe␈αlabel␈αhas␈α␈↓↓not␈↓␈αbeen␈αpreviously␈αdefined␈αbut␈αhas␈αbeen␈αreferenced␈αthen␈αthe␈α
atom␈αwill
␈↓ ↓H␈↓have␈αan␈αindicator␈α␈↓αUNDEF␈↓;␈αthe␈αvalue-part␈αwill␈αbe␈αa␈αlist␈αof␈αall␈αthose␈αlocations␈αwhich␈αreference␈αthat
␈↓ ↓H␈↓label.␈α
Since␈αwe␈α
will␈αonly␈α
be␈α
doing␈αsimple␈α
fixups,␈αthis␈α
will␈α
be␈αsufficient.␈α
The␈αcontents␈α
of␈αany␈α
location
␈↓ ↓H␈↓referenced␈αfrom␈α
such␈αa␈α
fixup␈αlist␈αwill␈α
be␈αa␈α
partially␈αassembled␈αword␈↓π 204␈↓␈α
with␈αthe␈α
memory␈αaddress
␈↓ ↓H␈↓portion␈αset␈αto␈α0.␈αWhen␈αthe␈αlabel␈αfinally␈αis␈αdefined␈αwe␈αmust␈αperform␈αthe␈αfixups,␈αdelete␈αthe␈α␈↓αUNDEF␈↓
␈↓ ↓H␈↓pair,␈αand␈αadd␈α
a␈α␈↓αSYM␈↓␈αpair.␈α There␈α
are␈αtwo␈αmain␈α
functions.␈α␈↓αdefloc␈↓␈αis␈αcalled␈α
when␈αa␈αlabel␈α
has␈αbeen
␈↓ ↓H␈↓defined;␈αif␈αthere␈αare␈αno␈αpending␈αforward␈αreferences␈αthen␈αthe␈α␈↓αSYM␈↓␈αpair␈αis␈αsimply␈αadded,␈αotherwise
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 204␈↓ which may be instruction or data
␈↓ ↓H␈↓␈↓↓310 Dynamic Structure␈↓ 46.8␈↓
␈↓ ↓H␈↓the␈αfixup␈αmechanism␈αis␈αexercised.␈αWhen␈αa␈αlabel␈αis␈αreferenced,␈α␈↓αgval␈↓␈αis␈αcalled.␈αIf␈αthe␈αlabel␈αis␈αalready
␈↓ ↓H␈↓defined then it simply returns the ␈↓αSYM␈↓ value; otherwise it adds a forward reference to the list.
␈↓ ↓H␈↓αdefloc <= λ[[lab;loc] prog[[z]
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧_[null[z ← get[lab;UNDEF]] → go[a]]
␈↓ ↓H␈↓α␈↓ β(fixup␈↓ ∧_deposit[␈↓ ¬λcar[z];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧_␈↓ ¬λfixit[examine[car[z]];loc]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧_[z ← cdr[z] → go[fixup]]
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧_remprop[lab;UNDEF];
␈↓ ↓H␈↓α␈↓ β(a␈↓ ∧_return[putprop[lab;loc;SYM]]
␈↓ ↓H␈↓αgval <= λ[[lab]␈↓ βλ[get[lab;SYM];
␈↓ ↓H␈↓α␈↓ βλ ␈↓
t␈↓α → putprop[lab;cons[loc;get[lab;UNDEF]];UNDEF]; 0]]
␈↓ ↓H␈↓␈↓αfixit <= λ[[x;l] mkinstr[op[x];ac[x];add[x];l]]␈↓
␈↓ ↓H␈↓Notes: these functions use lots of tricks.
␈↓ ↓H␈↓␈↓ αh␈↓↓1.␈↓␈αIn␈α␈↓αdefloc␈↓␈αwe␈αuse␈α␈↓αget␈↓␈αas␈αa␈αpredicate,␈αrelying␈αon␈αour␈αconvention␈αthat␈αa␈αnon-␈↓αNIL␈↓␈αvalue
␈↓ ↓H␈↓␈↓ β(represents truth (Section 5.5).
␈↓ ↓H␈↓␈↓ αh␈↓↓2.␈↓␈α
In␈α∞that␈α
same␈α∞conditional,␈α
we␈α∞also␈α
rely␈α
on␈α∞the␈α
fact␈α∞that␈α
the␈α∞value␈α
of␈α∞an␈α
assignment
␈↓ ↓H␈↓␈↓ β(statement␈αis␈αthe␈α
value␈αof␈αits␈α
right␈αhand␈αside.␈αWe␈α
appeal␈αto␈αpoints␈α
␈↓↓1␈↓␈αand␈α␈↓↓2␈↓␈α
in␈αthe
␈↓ ↓H␈↓␈↓ β(second conditional of ␈↓αdefloc␈↓.
␈↓ ↓H␈↓␈↓ αh␈↓↓3.␈↓␈α⊃In␈α⊃␈↓αgval␈↓,␈α⊃there␈α⊃is␈α⊃no␈α⊃e␈↓β1␈↓;␈α⊃recalling␈α⊃(Section 5.5)␈α⊃that␈α⊃if␈α⊃p␈↓β1␈↓␈α⊃evaluates␈α∩to␈α⊃something
␈↓ ↓H␈↓␈↓ β(non-␈↓αNIL␈↓, then that value is the value of the conditional expression.
␈↓ ↓H␈↓␈↓ αh␈↓↓4.␈↓␈α∩We␈α⊃also␈α∩use␈α⊃an␈α∩extended␈α⊃conditional␈α∩in␈α⊃␈↓αgval␈↓,␈α∩executing␈α⊃the␈α∩␈↓αputprop␈↓␈α∩and␈α⊃then
␈↓ ↓H␈↓␈↓ β(returning ␈↓α0␈↓.
␈↓ ↓H␈↓␈↓ αh␈↓↓5.␈↓ Note also that ␈↓αloc␈↓ is a non-local variable in ␈↓αgval␈↓.
␈↓ ↓H␈↓␈↓ ∧v␈↓↓6.9 Compiling and Interpreting␈↓
␈↓ ↓H␈↓Before␈α∃adding␈α∃more␈α∃LISP␈α∃constructs␈α∃to␈α∃our␈α∃compiling␈α∃algorithm␈α∃we␈α∃should␈α∃reexamine␈α∀the
␈↓ ↓H␈↓relationships␈α∀between␈α∀compilers␈α∪and␈α∀interpreters.␈α∀ The␈α∪compilation␈α∀of␈α∀conditional␈α∪expressions
␈↓ ↓H␈↓introduces␈α⊂an␈α⊂interesting␈α⊂dichotomy␈α⊂between␈α⊂the␈α⊃action␈α⊂of␈α⊂an␈α⊂interpreter␈α⊂and␈α⊂that␈α⊂of␈α⊃a␈α⊂typical
␈↓ ↓H␈↓compiler.
␈↓ ↓H␈↓We␈α∞will␈α∞restrict␈α∞ourselves␈α∞to␈α∞a␈α∞simple␈α∞form␈α∞of␈α∞the␈α∞conditional␈α∞expression: ␈α∞␈↓αif[p;then;otherwise]␈↓,
␈↓ ↓H␈↓where␈α⊂␈↓αp␈↓␈α⊂is␈α⊂a␈α∂an␈α⊂expression␈α⊂giving␈α⊂␈↓
t␈↓␈α∂or␈α⊂␈↓
f␈↓;␈α⊂␈↓αthen␈↓␈α⊂is␈α∂the␈α⊂expression␈α⊂to␈α⊂be␈α∂evaluated␈α⊂if␈α⊂␈↓αp␈↓␈α⊂gives␈α∂␈↓
t␈↓;
␈↓ ↓H␈↓␈↓↓6.9␈↓ π⎇Compiling and Interpreting 311␈↓
␈↓ ↓H␈↓otherwise␈α∂the␈α∂expression,␈α⊂␈↓αotherwise␈↓,␈α∂is␈α∂to␈α∂be␈α⊂evaluated.␈α∂It␈α∂is␈α∂an␈α⊂easy␈α∂exercise␈α∂to␈α∂express␈α⊂a␈α∂LISP
␈↓ ↓H␈↓conditional in terms of a nested ␈↓αif␈↓ expression.
␈↓ ↓H␈↓When␈α⊃an␈α⊃interpreter␈α⊃evaluates␈α∩conditional␈α⊃expression␈α⊃or␈α⊃an␈α⊃␈↓αif␈↓,␈α∩it␈α⊃will␈α⊃evaluate␈α⊃either␈α∩␈↓αthen␈↓␈α⊃or
␈↓ ↓H␈↓␈↓αotherwise␈↓;␈αnot␈αboth.␈α
When␈αa␈αcompiler␈α
compiles␈αcode␈αfor␈α
an␈α␈↓αif␈↓␈αexpression,␈α
it␈αcompiles␈α␈↓↓both␈↓␈α
branches.
␈↓ ↓H␈↓This␈αloss␈αof␈αsymmetry␈αis␈αdisconcerting.␈αCertainly,␈αwe␈αcannot␈αonly␈αcompile␈α␈↓↓one␈↓␈αbranch␈αof␈αthe␈α␈↓αif␈↓␈αand
␈↓ ↓H␈↓claim␈α∪that␈α∪we␈α∩have␈α∪faithfully␈α∪translated␈α∩a␈α∪conditional;␈α∪however,␈α∩compiling␈α∪code␈α∪for␈α∩program
␈↓ ↓H␈↓segments␈αwhich␈α
may␈αnot␈αbe␈α
executed␈αis␈αalso␈α
disconcerting.␈αFor␈αexample,␈α
if␈αa␈α
particular␈αevaluation
␈↓ ↓H␈↓␈↓↓never␈↓␈α⊂takes␈α⊂the␈α⊂␈↓αotherwise␈↓␈α⊃branch␈α⊂of␈α⊂a␈α⊂conditional␈↓π 205␈↓,␈α⊂then␈α⊃we␈α⊂need␈α⊂not␈α⊂compile␈α⊂code␈α⊃for␈α⊂that
␈↓ ↓H␈↓branch.␈α At␈α
a␈αlater␈αdate,␈α
a␈αdifferent␈αevaluation␈α
might␈αtake␈αthat␈α
branch,␈αand␈αat␈α
that␈αtime,␈αwe␈α
should
␈↓ ↓H␈↓be␈αable␈αto␈αcompile␈αit.␈α We␈αwill␈αdiscuss␈αmore␈αimplications␈αof␈αthis␈αbehavior␈αin␈αSection 6.21␈αwhen␈αwe
␈↓ ↓H␈↓examine␈αthe␈αinteractive␈αprogramming␈αaspects␈αof␈αLISP.␈α This␈αsection␈αwill␈αdeal␈αwith␈αthe␈αmechanical
␈↓ ↓H␈↓aspects of reconciling compilers with interpreters.
␈↓ ↓H␈↓We␈α⊃will␈α⊃show␈α∩that␈α⊃it␈α⊃is␈α⊃possible␈α∩to␈α⊃interpret␈α⊃␈↓↓and␈↓␈α⊃compile␈α∩at␈α⊃the␈α⊃same␈α⊃time␈↓π 206␈↓.␈α∩The␈α⊃relevant
␈↓ ↓H␈↓observation␈αis␈αthat␈αmuch␈αof␈αthe␈αcompiling␈αand␈αinterpreting␈αalgorithms␈αare␈αidentical;␈αthey␈αdeal␈αwith
␈↓ ↓H␈↓decoding␈α
the␈α∞input␈α
expression␈α
and␈α∞the␈α
understanding␈α
of␈α∞which␈α
LISP␈α
constructs␈α∞are␈α
present.␈α∞It␈α
is
␈↓ ↓H␈↓only␈αafter␈αthe␈αinterpreter␈αor␈αcompiler␈αhas␈αdiscovered␈αthe␈αnature␈αof␈αthe␈αexpression␈αthat␈αthe␈αspecifics
␈↓ ↓H␈↓of compilation or interpretation come into play.
␈↓ ↓H␈↓We␈α∪will␈α∪build␈α∪an␈α∪evaluator/compiler␈α∪named␈α∪␈↓αevcom␈↓␈α∪based␈α∪on␈α∪the␈α∪explicit␈α∪access␈α∀evaluator␈α∪of
␈↓ ↓H␈↓Section 4.6.␈α⊃ It␈α⊃will␈α⊂handle␈α⊃compilation␈α⊃and␈α⊂interpretation␈α⊃of␈α⊃the␈α⊂application␈α⊃of␈α⊃both␈α⊂primitive
␈↓ ↓H␈↓functions␈α⊃and␈α⊂named␈α⊃λ-definitions;␈α⊂it␈α⊃will␈α⊂recognize␈α⊃the␈α⊂difference␈α⊃between␈α⊂local␈α⊃and␈α⊂non-local
␈↓ ↓H␈↓variable␈α∞references,␈α∞compiling␈α∞(and␈α∞executing)␈α∞calls␈α
on␈α∞␈↓αlookup␈↓␈α∞for␈α∞non-local␈α∞references,␈α∞and␈α∞use␈α
a
␈↓ ↓H␈↓faster␈α∞relative␈α∂addressing␈α∞technique␈α∂for␈α∞local␈α∞variables.␈α∂ Finally␈α∞it␈α∂will␈α∞"incrementally␈α∂compile"␈α∞␈↓αif␈↓
␈↓ ↓H␈↓expressions,␈α
executing␈α
(and␈α
generating␈α
code␈α
for)␈α
the␈α
branch␈α
designated␈α
by␈α
the␈α
predicate;␈α
and␈α
will
␈↓ ↓H␈↓leave␈α
sufficient␈αinformation␈α
available␈αsuch␈α
that␈αif␈α
ever␈αthe␈α
other␈αbranch␈α
is␈αexecuted,␈α
then␈α
code␈αis
␈↓ ↓H␈↓compiled for it.
␈↓ ↓H␈↓Before␈α∞sketching␈α
␈↓αevcom␈↓,␈α∞one␈α
other␈α∞implementation␈α∞detail␈α
is␈α∞worth␈α
mentioning.␈α∞ We␈α∞cannot␈α
simply
␈↓ ↓H␈↓replace␈α
a␈αLISP␈α
expression␈αwith␈α
compiled␈α
code;␈αLISP␈α
expressions␈αare␈α
data␈αstructures␈α
and␈α
we␈αmust
␈↓ ↓H␈↓be␈α
able␈αto␈α
operate␈αon␈α
that␈αdata␈α
structure␈αrepresentation␈α
without␈αbeing␈α
aware␈αthat␈α
a␈αcompilation␈α
has
␈↓ ↓H␈↓occurred.␈α⊃ For␈α∩example␈α⊃the␈α∩LISP␈α⊃editor␈α∩(Section 6.22)␈α⊃must␈α∩be␈α⊃able␈α∩to␈α⊃manipulate␈α∩the␈α⊃S-expr
␈↓ ↓H␈↓representation.␈α∩ So␈α∩rather␈α∩than␈α∩replace␈α∩expressions␈α∩with␈α∩code␈α∩we␈α∩␈↓↓associate␈↓␈α∩the␈α∩code␈α∩with␈α⊃the
␈↓ ↓H␈↓expression␈α_using␈α_an␈α_association␈α_list␈α_whose␈α_name-entries␈α_are␈α_LISP␈α_expressions␈α_and␈α_whose
␈↓ ↓H␈↓value-entries␈α
are␈αsequences␈α
of␈αinstructions␈↓π 207␈↓.␈α
The␈αvariable␈α
␈↓αcode␈↓␈α
is␈αused␈α
to␈αhold␈α
the␈αassociation␈α
list
␈↓ ↓H␈↓or code buffer.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 205␈↓ That does ␈↓↓not␈↓ imply that the ␈↓αotherwise␈↓-branch will ␈↓↓never␈↓ be visited.
␈↓ ↓H␈↓␈↓π 206␈↓ See [Mit 70] for a similar idea applied to a different language.
␈↓ ↓H␈↓␈↓π 207␈↓␈α⊃In␈α⊃actual␈α⊃practice,␈α⊃such␈α⊃a␈α⊃representation␈α⊃would␈α⊃be␈α⊃prohibitively␈α⊃expensive␈α⊃and␈α∩we␈α⊃would
␈↓ ↓H␈↓substitute a hash array technique; see Section 7.13.
␈↓ ↓H␈↓␈↓↓312 Dynamic Structure␈↓ 56.9␈↓
␈↓ ↓H␈↓Finally␈αhere␈αis␈αthe␈αsketch.␈αWe␈αhave␈αleft␈αout␈αmany␈αof␈αthe␈αsubsidiary␈αfunctions␈αand␈αhave␈αleft␈αout␈αall
␈↓ ↓H␈↓of␈α⊃the␈α⊂execution␈α⊃mechanism␈α⊂involved␈α⊃in␈α⊂␈↓αxct␈↓␈α⊃and␈α⊂␈↓αexecute␈↓;␈α⊃␈↓αxct␈↓␈α⊂executes␈α⊃a␈α⊂single␈α⊃instruction␈α⊂and
␈↓ ↓H␈↓␈↓αexecute␈↓ basically is a combined assembler and execution device.
␈↓ ↓H␈↓αevcom <= λ[[exp]prog[[z]
␈↓ ↓H␈↓α␈↓ β(return[␈↓ ∧λ[z ← hascode[exp] → execute[z];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ isconst[exp] → xct1[list[mksend[exp]]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ isvar[exp] →␈↓ ¬8[z ← islocal[exp] → xct1[send_code[list[mklocal[z]]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ␈↓ ¬8 z ← isfun[exp] → send_code[evcom1[def[z];()]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ␈↓ ¬8 issubr[exp] → send_code[list[mkpushj[exp]]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ␈↓ ¬8 ␈↓
t␈↓α → xct1[send_code[list[mkglob[exp]]]]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ isif[exp] → send_code[evif[exp]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ ␈↓
t␈↓α → send_code[mkcode[␈↓ ε8xct1[list[mkalloc[vars[fun[exp]]]]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ␈↓ ¬8␈↓ ε8evcomlist[args[exp]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧λ␈↓ ¬8␈↓ ε8xct1[list[mkcall[fun[exp]]]]] ]]] ]]
␈↓ ↓H␈↓αevcom1 <= λ[[exp;code] evcom[exp]]
␈↓ ↓H␈↓αxct1 <= λ[[x] xct[x]; x]
␈↓ ↓H␈↓Here's␈α
the␈α
essence␈α
of␈α
␈↓αevcom␈↓:␈α
if␈α
the␈α
expression␈αhas␈α
code␈α
in␈α
the␈α
current␈α
code␈α
buffer,␈α
then␈α
we␈αexecute␈α
it
␈↓ ↓H␈↓without␈αfurther␈αprocessing.␈αA␈αconstant␈αis␈αexecuted␈αand␈αproduces␈αcode,␈αsince␈αthat␈αconstant␈αmay␈αbe␈αa
␈↓ ↓H␈↓subexpression␈αof␈αa␈αlarger␈αexpression␈αbeing␈αcompiled;␈αwe␈αdo␈αnot␈αsave␈αthe␈αconstant␈αcode␈αin␈αthe␈αcode
␈↓ ↓H␈↓buffer.␈αTwo␈αtypes␈αof␈αvariables␈αare␈αrecognized:␈αa␈αlocal␈αvariable␈αis␈αrecognized␈αby␈αits␈αpresence␈αin␈αthe
␈↓ ↓H␈↓local␈αtable;␈αa␈αrelative␈αaddress␈αreference␈αcan␈αbe␈αgiven␈αfor␈αthat␈αentry.␈αMore␈αwill␈αbe␈αsaid␈αabout␈αrapid
␈↓ ↓H␈↓access␈α⊂to␈α⊂local␈α⊂variables␈α⊂in␈α⊂Section 6.10␈α⊃and␈α⊂Section 6.11.␈α⊂If␈α⊂the␈α⊂variable␈α⊂reference␈α⊃is␈α⊂non-local,
␈↓ ↓H␈↓then␈α∂we␈α∂compile␈α∂a␈α∂version␈α∂of␈α∂␈↓αlookup␈↓;␈α∂the␈α⊂actual␈α∂form␈α∂of␈α∂that␈α∂code␈α∂will␈α∂depend␈α∂on␈α⊂the␈α∂binding
␈↓ ↓H␈↓implementation (shallow or deep). Either type of variable reference saves the code using ␈↓αsend_code␈↓.
␈↓ ↓H␈↓If␈αthe␈α
variable␈αreference␈α
is␈αto␈αa␈α
function␈αname,␈α
then␈αwe␈αwill␈α
have␈αgotten␈α
here␈αthrough␈α
a␈αfunction
␈↓ ↓H␈↓application.␈α
We␈α
must␈α
compile␈α
and␈α
execute␈α∞code␈α
for␈α
that␈α
function␈α
definition.␈α
We␈α
use␈α∞the␈α
function
␈↓ ↓H␈↓␈↓αevcom1␈↓␈α∂since␈α∂the␈α∂code␈α∂buffer,␈α∂␈↓αcode␈↓,␈α∂must␈α∂be␈α∂re-initialized␈α∂within␈α∂the␈α∂compilation␈α∂of␈α⊂the␈α∂function
␈↓ ↓H␈↓body␈α∞since␈α∞code␈α∞in␈α∞the␈α∞outer␈α∞environment␈α∞won't␈α∞be␈α∞valid␈α∞within␈α∞the␈α∞function␈α∞body.␈α∂ Finally,␈α∞the
␈↓ ↓H␈↓variable␈αmight␈αbe␈αa␈αreference␈αto␈αa␈αprimitive␈αfunction,␈αin␈αwhich␈αcase␈αwe␈αjust␈αreturn␈αthe␈αcall␈αand␈αlet
␈↓ ↓H␈↓the function application execute it.
␈↓ ↓H␈↓The ␈↓αif␈↓ statement is discussed below.
␈↓ ↓H␈↓If␈αthe␈αexpression␈αis␈αan␈αapplication,␈αwe␈αgenerate␈α(and␈αexecute)␈αa␈αsequence␈αof␈αcode␈αto␈αallocate␈αspace,
␈↓ ↓H␈↓compile␈α∞and␈α
execute␈α∞the␈α∞argument␈α
list,␈α∞and␈α∞if␈α
necessary␈α∞compile,␈α∞but␈α
always␈α∞execute␈α∞the␈α
function
␈↓ ↓H␈↓call. The code sequence is constructed using ␈↓αmkcode␈↓; you may think of ␈↓αmkcode␈↓ as ␈↓αappend␈↓.
␈↓ ↓H␈↓αhascode <= λ[[exp] prog[[z]
␈↓ ↓H␈↓α␈↓ ∧_return[␈↓ ∧h[z ← findcode[exp] → cdr[z];
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ∧h ␈↓
t␈↓α → ␈↓
f␈↓]]]]
␈↓ ↓H␈↓␈↓↓6.9␈↓ π⎇Compiling and Interpreting 313␈↓
␈↓ ↓H␈↓αevcomlist <= λ[[l]␈↓ β([null[l] → ();
␈↓ ↓H␈↓α␈↓ β( null[rest[l]] → evcom[first[l]];
␈↓ ↓H␈↓α␈↓ β( ␈↓
t␈↓α → mkcode[␈↓ ∧Hevcom[first[l]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧Hxct1[((NEXT))];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧Hevcomlist[rest[l]]]]]
␈↓ ↓H␈↓αevif <= λ[[exp] prog[␈↓ βX[l p a b]
␈↓ ↓H␈↓α␈↓ βXl ← body[exp];
␈↓ ↓H␈↓α␈↓ βXp ← pred[l];
␈↓ ↓H␈↓α␈↓ βXa ← ante[l];
␈↓ ↓H␈↓α␈↓ βXb ← ow[l];
␈↓ ↓H␈↓α␈↓ βXp ← evcom[p];
␈↓ ↓H␈↓α␈↓ βXreturn[list[␈↓ ∧h[receive[] → mkifa[exp;p;evcom[a];b];
␈↓ ↓H␈↓α␈↓ βX␈↓ ∧h ␈↓
t␈↓α → mkifb[exp;p;a;evcom[b]]]]] ]]
␈↓ ↓H␈↓The␈αcompilation␈αand␈αexecution␈αof␈α␈↓αif␈↓␈αexpressions␈αis␈αinteresting.␈α When␈αcompiling␈αthe␈αfirst␈αreference
␈↓ ↓H␈↓to␈αan␈α
␈↓αif␈↓␈αinstance,␈α
we␈αcompile␈α
the␈αpredicate␈α
and␈αone␈α
of␈αthe␈α
branches;␈αwe␈α
associate␈αa␈α
structure␈αwith
␈↓ ↓H␈↓the␈α∪instance;␈α∩that␈α∪structure␈α∩has␈α∪either␈α∩the␈α∪name␈α∩␈↓αifa␈↓␈α∪or␈α∩␈↓αifb␈↓␈α∪depending␈α∩on␈α∪which␈α∪branch␈α∩was
␈↓ ↓H␈↓compiled.␈α
If␈α
we␈α
come␈α
across␈α
this␈α
instance␈α
of␈α
␈↓αif␈↓␈α
again␈α
(either␈α
in␈α
a␈α
loop␈α
or␈α
in␈α
a␈α
recursion)␈α
then␈αwe
␈↓ ↓H␈↓find␈αthe␈α␈↓αifa␈↓␈α
or␈α␈↓αifb␈↓␈αentry␈αin␈α
␈↓αcode␈↓.␈αIf␈αwe␈αpick␈α
the␈αsame␈αbranch␈αof␈α
the␈α␈↓αif␈↓␈αthen␈αnothing␈α
new␈αhappens;
␈↓ ↓H␈↓but␈α
if␈α
the␈α
(compiled)␈α
predicate␈α
evaluated␈α
to␈α
the␈α
other␈α
truth␈α
value,␈α
then␈α
we␈α
compile␈α
the␈α
other␈α
branch
␈↓ ↓H␈↓and␈αassociate␈αa␈α
completely␈αcompiled␈αprogram␈α
with␈αthe␈αoriginal␈α
␈↓αif␈↓␈αexpression.␈α The␈α
construction␈αof
␈↓ ↓H␈↓the completed code is the business of the next function, ␈↓αmkifcode␈↓.
␈↓ ↓H␈↓αmkifcode <= λ[[p;a;b]
␈↓ ↓H␈↓α␈↓ βHλ[[l;l1] mkcode[␈↓ ¬_p;
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬_list[mkjumpf[l]];
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬_a;
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬_list[mkjump[l1]];
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬_list[l];
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬_b;
␈↓ ↓H␈↓α␈↓ βH␈↓ ¬_list[l1]]]
␈↓ ↓H␈↓α␈↓ βH [gensym[];gensym[]] ]
␈↓ ↓H␈↓␈↓↓314 Dynamic Structure␈↓ 56.9␈↓
␈↓ ↓H␈↓␈↓↓Recognizers␈↓α
␈↓ ↓H␈↓αislocal <= λ[[x]in[x;local[env]]]
␈↓ ↓H␈↓αisif <= λ[[x] eq[first[x] IF]]
␈↓ ↓H␈↓αisprim <= λ[[ins] get[ins;INST]]
␈↓ ↓H␈↓αisfun <= λ[[x] get[x; EXPR]]
␈↓ ↓H␈↓α␈↓↓Constructors␈↓α
␈↓ ↓H␈↓αmklocal <= λ[[var] list[SEND@;var]]
␈↓ ↓H␈↓αmkglob <= λ[[x] list[LOOKUP;x]]
␈↓ ↓H␈↓αmkalloc <= λ[[vars] list[ALLOC;vars]]
␈↓ ↓H␈↓αmkcall <= λ[[fn] list[CALL;fn]]
␈↓ ↓H␈↓We␈α
have␈α
left␈αout␈α
a␈α
significant␈α
amount␈αof␈α
detail␈α
and␈αwe␈α
have␈α
only␈α
covered␈αa␈α
subset␈α
of␈α
LISP,␈αbut
␈↓ ↓H␈↓the␈α∪result␈α∀should␈α∪be␈α∀understandable;␈α∪and␈α∪it␈α∀should␈α∪further␈α∀clarify␈α∪the␈α∀relationships␈α∪between
␈↓ ↓H␈↓compilation␈α
and␈α
interpretation.␈α
Typical␈α
discussions␈αof␈α
compilers␈α
and␈α
interpreters␈α
lead␈α
one␈αto␈α
believe
␈↓ ↓H␈↓that␈α∩there␈α∩is␈α⊃a␈α∩severe␈α∩flexibility/efficiency␈α⊃tradeoff␈α∩imposed␈α∩in␈α⊃dealing␈α∩with␈α∩compilers.␈α∩If␈α⊃you
␈↓ ↓H␈↓compile␈αprograms␈αyou␈αmust␈αgive␈αup␈αa␈αlot␈αof␈αflexibility␈αin␈αediting␈αand␈αdebugging.␈α With␈αa␈αproperly
␈↓ ↓H␈↓designed language and machine that is not true.
␈↓ ↓H␈↓␈↓ ∧␈↓↓6.10 A compiler for Simple ␈↓αeval␈↓↓: The Value Stack␈↓α
␈↓ ↓H␈↓We␈α∞wish␈α∞to␈α∞add␈α∞more␈α∞details␈α∞to␈α∞our␈α∞basic␈α∞compiling␈α∞algorithms.␈α∞For␈α∞simplicity,␈α∞we␈α∞return␈α∞to␈α
the
␈↓ ↓H␈↓pure␈α_compiler.␈α_We␈α_develop␈α_a␈α_more␈α_complex␈α_compiler,␈α_leaving␈α_the␈α_details␈α_of␈α→a␈α_complex
␈↓ ↓H␈↓compiler/interpreter to the reader.
␈↓ ↓H␈↓The␈α∂major␈α⊂failing␈α∂of␈α∂the␈α⊂previous␈α∂␈↓αcompexp␈↓␈α∂(Section 6.5)␈α⊂is␈α∂its␈α∂inability␈α⊂to␈α∂handle␈α⊂variables.␈α∂ A
␈↓ ↓H␈↓related␈αfailing␈αis␈αits␈αinability␈αto␈αcompile␈αcode␈αfor␈αλ-definitions.␈αWe␈αwill␈αalleviate␈αboth␈αdifficulties␈αin
␈↓ ↓H␈↓this section.
␈↓ ↓H␈↓From page 299, we know what ␈↓αcompexp␈↓ will do with:
␈↓ ↓H␈↓␈↓ ε∧␈↓αf[g[A];h[B]]␈↓
␈↓ ↓H␈↓α␈↓ αX(MOVE 1 (QUOTE A))␈↓ πλ␈↓; get ␈↓αA␈↓ into ␈↓α1.
␈↓ ↓H␈↓α␈↓ αX(CALL G)␈↓ πλ␈↓; call the function named ␈↓αg
␈↓ ↓H␈↓α␈↓ αX(PUSH P 1)␈↓ πλ␈↓; save the value␈↓α
␈↓ ↓H␈↓α␈↓ αX(MOVE 1 (QUOTE B))␈↓ πλ␈↓; get ␈↓αB␈↓ into ␈↓α1
␈↓ ↓H␈↓α␈↓ αX(PUSHJ P H)␈↓ πλ␈↓; call ␈↓αh
␈↓ ↓H␈↓α␈↓ αX(MOVE 2 1)␈↓ πλ␈↓; restore the arguments in␈↓α
␈↓ ↓H␈↓α␈↓ αX(POP P 1)␈↓ πλ␈↓; preparation for␈↓α
␈↓ ↓H␈↓α␈↓ αX(CALL F)␈↓ πλ␈↓; calling ␈↓αf
␈↓ ↓H␈↓␈↓↓6.10␈↓ ε≤A compiler for Simple ␈↓αeval␈↓↓: The Value Stack 315␈↓α
␈↓ ↓H␈↓No suprises yet. What would we expect to see for a compiled version of:
␈↓ ↓H␈↓␈↓ ¬␈␈↓αf[g[x];h[y]]␈↓ ?
␈↓ ↓H␈↓We␈α
␈↓↓should␈↓␈α
expect␈α
to␈α
see␈α
the␈α
same␈α
code␈α
except␈α
that␈α
we␈α
would␈α
have␈α
instructions␈α
to␈α
send␈α
the␈α
values␈α
of
␈↓ ↓H␈↓␈↓αx␈↓␈αand␈α␈↓αy␈↓␈αinto␈α␈↓α1␈↓␈αat␈αthe␈αappropriate␈αtime.␈αSo␈αthe␈αfirst␈αproblem␈αis␈αhow␈αto␈αfind␈αthe␈αvalues␈αof␈αvariables.
␈↓ ↓H␈↓Assume we are really interested in compiling:
␈↓ ↓H␈↓␈↓ ¬8␈↓αj <= λ[[x;y] f[g[x];h[y]]]␈↓
␈↓ ↓H␈↓This␈αadded␈αproblem␈αmakes␈αour␈α
question␈αeasier.␈αConsider␈αa␈αcall␈α
on␈α␈↓αj␈↓:␈α␈↓αj[A;B]␈↓,␈αfor␈αexample.␈αWe␈α
know
␈↓ ↓H␈↓that␈αthe␈α
execution␈αof␈αthe␈α
call␈αoccurs␈αafter␈α
the␈αvalues␈α␈↓αA␈↓␈α
and␈α␈↓αB␈↓␈αhave␈α
been␈αset␈αup␈α
in␈α␈↓αAC1␈↓␈α
and␈α␈↓αAC2␈↓.
␈↓ ↓H␈↓Thus␈αat␈α␈↓↓that␈↓␈αtime␈αwe␈αdo␈αindeed␈αknow␈αwhat␈αthe␈αvalues␈αof␈α␈↓αx␈↓␈αand␈α␈↓αy␈↓␈αare␈αsupposed␈αto␈αbe.␈αFor␈αsake␈αof
␈↓ ↓H␈↓simplicity,␈αassume␈αthat␈αthe␈αvariables␈α␈↓αx␈↓␈αand␈α␈↓αy␈↓␈αare␈αstrictly␈αlocal.␈αThat␈αis,␈αno␈αone␈αwithin␈αthe␈αbodies␈αof
␈↓ ↓H␈↓either␈α
␈↓αg␈↓␈αor␈α
␈↓αh␈↓␈αuses␈α
␈↓αx␈↓␈αor␈α
␈↓αy␈↓␈αfree;␈α
we␈αwill␈α
worry␈αabout␈α
compilation␈αof␈α
free␈αreferences␈α
later.␈α
Since␈αthey
␈↓ ↓H␈↓are␈αlocal,␈αthen␈αonly␈α␈↓αj␈↓␈αneeds␈α
to␈αfind␈αtheir␈αvalues.␈α We␈αcannot␈α
leave␈αthe␈αvalues␈αin␈αthe␈α␈↓αAC␈↓s␈αsince␈α
those
␈↓ ↓H␈↓registers are needed for other computations. Rather, we will save ␈↓αx␈↓ and ␈↓αy␈↓ in the top of the stack ␈↓αP␈↓.
␈↓ ↓H␈↓Since␈α␈↓αP␈↓␈αcontains␈αthe␈αvalues␈αof␈αpartial␈αcomputations,␈αand␈αnow␈αalso␈αcontains␈αthe␈αvalues␈αof␈αthe␈αlocal
␈↓ ↓H␈↓λ-variables,␈α∂␈↓αP␈↓␈α⊂is␈α∂also␈α∂called␈α⊂the␈α∂␈↓↓value␈α∂stack␈↓.␈α⊂This␈α∂is␈α∂a␈α⊂value␈α∂stack␈α∂similar␈α⊂to␈α∂that␈α⊂described␈α∂in
␈↓ ↓H␈↓deep-binding␈α⊂(Section 5.18);␈α⊂however␈α∂we␈α⊂do␈α⊂not␈α⊂need␈α∂the␈α⊂name␈α⊂stack␈α∂here.␈α⊂This␈α⊂is␈α⊂because␈α∂the
␈↓ ↓H␈↓compiler␈α∞will␈α∂␈↓↓know␈↓␈α∞where␈α∞on␈α∂the␈α∞stack␈α∞values␈α∂of␈α∞local␈α∞variables␈α∂can␈α∞be␈α∞found.␈α∂It␈α∞will␈α∂put␈α∞them
␈↓ ↓H␈↓there␈α
so␈α
it␈α␈↓↓should␈↓␈α
know.␈α
This␈α
lack␈αof␈α
a␈α
name␈α
stack␈αis␈α
a␈α
mixed␈α
blessing;␈αwe␈α
save␈α
space,␈α
but␈αwe␈α
have
␈↓ ↓H␈↓lost␈α
the␈α
names,␈α
which␈α
are␈α
useful␈α
if␈α
we␈α
are␈αdebugging␈α
code.␈α
Note␈α
␈↓αP␈↓␈α
is␈α
not␈α
solely␈α
a␈α
value␈α
stack;␈αit
␈↓ ↓H␈↓also␈α∃contains␈α∃the␈α⊗control␈α∃information.␈α∃ We␈α⊗are␈α∃not␈α∃always␈α∃able␈α⊗to␈α∃mix␈α∃access␈α⊗and␈α∃control
␈↓ ↓H␈↓information␈α⊃on␈α⊃one␈α⊃stack;␈α⊃in␈α⊃fact,␈α⊃we␈α⊃know␈α⊃that␈α⊃a␈α⊃stack␈α⊃is␈α⊃not␈α⊃always␈α⊃a␈α⊃sufficent␈α⊃vehicle␈α⊂for
␈↓ ↓H␈↓describing␈α∀LISP's␈α∀access␈α∪requirements.␈α∀ However,␈α∀a␈α∪very␈α∀large␈α∀subset␈α∪of␈α∀LISP␈α∀␈↓↓does␈↓␈α∀allow␈α∪a
␈↓ ↓H␈↓single-stack implementation, and we will be compiling within that subset for most of this chapter.
␈↓ ↓H␈↓Addressing␈α⊃the␈α⊃task␈α⊃at␈α⊃hand,␈α⊃the␈α⊃instructions␈α⊃for␈α⊃the␈α⊃body␈α⊃of␈α⊃␈↓αj␈↓␈α⊃will␈α⊃be␈α⊃very␈α⊃similar␈α⊃to␈α⊃those
␈↓ ↓H␈↓displayed␈α∃for␈α∃␈↓αf[g[A];h[B]]␈↓.␈α∃ We␈α∃will␈α∃generate␈α⊗instructions␈α∃to␈α∃save␈α∃the␈α∃values␈α∃on␈α⊗the␈α∃actual
␈↓ ↓H␈↓parameters by prefixing the ␈↓αcompexp␈↓-code with two ␈↓αPUSH␈↓ operations:
␈↓ ↓H␈↓α␈↓ ¬X(PUSH P 1)
␈↓ ↓H␈↓α␈↓ ¬X(PUSH P 2)
␈↓ ↓H␈↓After␈α
execution␈α
of␈α
this␈α
pair␈α
of␈α
instructions,␈α
called␈α
the␈α
␈↓↓prolog␈↓,␈α
the␈α
value␈α
of␈α
␈↓αy␈↓␈α
is␈α
on␈α
the␈α
top␈α
of␈αthe
␈↓ ↓H␈↓stack, and the value of ␈↓αx␈↓ is the next element down␈↓π 208␈↓.
␈↓ ↓H␈↓Now␈α
that␈αwe␈α
have␈α
saved␈αthe␈α
values,␈αwe␈α
need␈α
instructions␈αto␈α
␈↓αsend␈↓␈αthem␈α
to␈α
␈↓αAC1␈↓␈αwhen␈α
the␈α
value␈αis
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 208␈↓␈αThe␈αobservant␈αreader␈αwill␈αnote␈αthat␈αthe␈α␈↓αPUSH␈↓␈αfor␈α␈↓αx␈↓␈αis␈αunnecessary.␈α Since␈αwe␈α
have␈αassumed
␈↓ ↓H␈↓that␈α
␈↓αx␈↓␈α
and␈α
␈↓αy␈↓␈α
are␈α
strictly␈α
local,␈α
and␈α
since␈α
no␈αone␈α
else␈α
needs␈α
the␈α
value␈α
of␈α
␈↓αx␈↓␈α
except␈α
for␈α
␈↓αg[x]␈↓,␈α
we␈αcan
␈↓ ↓H␈↓simply␈α∩compute␈α⊃␈↓αg[x]␈↓␈α∩directly.␈α⊃One␈α∩might␈α⊃also␈α∩think␈α∩that␈α⊃we␈α∩could␈α⊃leave␈α∩␈↓αB␈↓␈α⊃in␈α∩␈↓αAC2␈↓␈α∩while␈α⊃we
␈↓ ↓H␈↓calculated ␈↓αg[x]␈↓; we cannot do that, as ␈↓αg[x]␈↓ might use ␈↓αAC2␈↓. We must ␈↓αPUSH␈↓ ␈↓αy␈↓.
␈↓ ↓H␈↓␈↓↓316 Dynamic Structure␈↓ )6.10␈↓
␈↓ ↓H␈↓needed.␈α∩We␈α∩will␈α∩implement␈α∩␈↓αsend@␈↓␈α∩using␈α⊃the␈α∩␈↓αMOVE␈↓␈α∩instruction␈α∩(Section 6.3).␈α∩In␈α∩this␈α∩case␈α⊃our
␈↓ ↓H␈↓memory␈αreference␈αwill␈α
be␈αrelative␈αto␈α
the␈αtop␈αof␈αthe␈α
stack␈α␈↓αP␈↓.␈α Relative␈α
addressing␈αis␈αdescribed␈αto␈α
our
␈↓ ↓H␈↓machine␈α∪with␈α∩a␈α∪memory␈α∩field␈α∪of␈α∩the␈α∪form␈α∩"␈↓αn P␈↓",␈α∪where␈α∩␈↓αn␈↓␈α∪designates␈α∩the␈α∪offset␈α∩into␈α∪␈↓αP␈↓␈α∩and
␈↓ ↓H␈↓references␈α
the␈α
␈↓αn␈↓πth␈↓␈α
element,␈α
counting␈α
backwards␈α
from␈α
zero.␈α
Thus␈α
in␈α
our␈α
current␈α
example␈α"␈↓α0 P␈↓"␈α
refers
␈↓ ↓H␈↓to␈α
the␈α
value␈αfor␈α
␈↓αy␈↓␈α
and␈α
"␈↓α-1 P␈↓"␈αrefers␈α
to␈α
␈↓αx␈↓␈α
at␈αthe␈α
time␈α
␈↓αj␈↓␈αis␈α
entered.␈α
Be␈α
sure␈αto␈α
realize␈α
also␈α
that␈αour
␈↓ ↓H␈↓addressing␈αis␈αrelative;␈αthough␈α␈↓α"0 P"␈↓␈αrefers␈αto␈α␈↓αy␈↓␈αat␈αentry␈αtime,␈α␈↓α0 P␈↓␈αwill␈α␈↓↓not␈↓␈αrefer␈αto␈α␈↓αy␈↓␈αwhen␈αwe␈αhave
␈↓ ↓H␈↓pushed␈αsomething␈α
onto␈αthe␈αstack.␈α
Be␈αsure␈α
to␈αrealize␈αthat␈α
we␈α␈↓↓cannot␈↓␈α
change␈αour␈αrelative␈α
addressing
␈↓ ↓H␈↓to␈α∞hard␈α∞machine␈α∞locations␈α∞in␈α
the␈α∞assembler.␈α∞The␈α∞addressing␈α∞must␈α
always␈α∞be␈α∞relative.␈α∞We␈α∞will␈α
be
␈↓ ↓H␈↓compiling␈α
code␈α
for␈α
recursive␈α
functions.␈α
Each␈α
recursive␈α
call␈α
must␈α
get␈α
a␈α
fresh␈α
segment␈α
of␈α
the␈α
value
␈↓ ↓H␈↓stack␈αin␈αwhich␈αto␈αstore␈αits␈αresults.␈αA␈αsimilar␈αproblem␈αappeared␈αwhen␈αwe␈αexamined␈αthe␈α␈↓αCALL-RET␈↓
␈↓ ↓H␈↓mechanism on page 292. There we were dealing with control information stored on a stack.
␈↓ ↓H␈↓Finally,␈αwe␈αcannot␈αleave␈αthe␈αcode␈αfor␈α␈↓αj␈↓␈αas␈αit␈αstands.␈αIf␈αthe␈αprolog␈αpushes␈αtwo␈αentries␈αonto␈αthe␈αstack
␈↓ ↓H␈↓then␈αwe␈αhad␈αbetter␈αconstruct␈αan␈αepilog␈αto␈αremove␈αthem;␈αotherwise␈αthe␈αstack␈αwill␈αnot␈αbe␈αin␈αthe␈αstate
␈↓ ↓H␈↓expected␈α
by␈αthe␈α
calling␈α
program.␈αAs␈α
we␈αleave␈α
␈↓αj␈↓␈α
we␈αsubtract␈α
␈↓α2␈↓␈αfrom␈α
the␈α
pointer␈α␈↓αP␈↓␈α
to␈αsynchronize␈α
the
␈↓ ↓H␈↓stack. The constant ␈↓α2␈↓ is designated as ␈↓α(C 2)␈↓. Finally we exit via ␈↓αRET␈↓.
␈↓ ↓H␈↓One␈α
further␈α
embellishment␈αis␈α
needed:␈α
since␈α
we␈αare␈α
defining␈α
a␈α
function␈αand␈α
turning␈α
it␈αinto␈α
compiled
␈↓ ↓H␈↓code,␈α∂we␈α∂must␈α∂preface␈α∂the␈α∂code␈α∂sequence␈α∂with␈α∂information␈α∂to␈α∂our␈α∂assembler␈α∂to␈α∂designate␈α∂␈↓αj␈↓␈α⊂as␈α∂a
␈↓ ↓H␈↓␈↓αSUBR␈↓.␈αThe␈αassembler␈αwill␈αmake␈αa␈αnew␈αproperty-value␈αpair␈αconsisting␈αof␈αthe␈αproperty␈αname␈α␈↓αSUBR␈↓
␈↓ ↓H␈↓and␈α
an␈αassociated␈α
property␈α
value␈αindicating␈α
the␈α
location␈αin␈α
BPS␈α
which␈αcontains␈α
the␈α
beginning␈αof
␈↓ ↓H␈↓the␈αcode␈αfor␈αthe␈αprocedure.␈αThat␈αpair␈αis␈αplaced␈αon␈αthe␈αp-list␈αof␈αthe␈αatom␈αrepresenting␈αthe␈αfunction
␈↓ ↓H␈↓name.
␈↓ ↓H␈↓α␈↓ αX(LAP J SUBR)␈↓ πλ␈↓; says ␈↓αj␈↓ is a function␈↓α
␈↓ ↓H␈↓α␈↓ αX(PUSH P 1)␈↓ πλ␈↓; save the input args␈↓α
␈↓ ↓H␈↓α␈↓ αX(PUSH P 2)
␈↓ ↓H␈↓α␈↓ αX(MOVE 1 -1 P)␈↓ πλ␈↓; get ␈↓αx
␈↓ ↓H␈↓α␈↓ αX(CALL G)␈↓ πλ␈↓; call the function named ␈↓αg
␈↓ ↓H␈↓α␈↓ αX(PUSH P 1)␈↓ πλ␈↓; save the value␈↓α
␈↓ ↓H␈↓α␈↓ αX(MOVE 1 -1 P)␈↓ πλ␈↓; get ␈↓αy
␈↓ ↓H␈↓α␈↓ αX(PUSHJ P H)␈↓ πλ␈↓; call ␈↓αh
␈↓ ↓H␈↓α␈↓ αX(MOVE 2 1)␈↓ πλ␈↓; set up the arguments in␈↓α
␈↓ ↓H␈↓α␈↓ αX(POP P 1)␈↓ πλ␈↓; preparation for␈↓α
␈↓ ↓H␈↓α␈↓ αX(CALL F)␈↓ πλ␈↓; calling ␈↓αf
␈↓ ↓H␈↓α␈↓ αX(SUB P (C 2))␈↓ πλ␈↓; synchronize the stack by removing
␈↓ ↓H␈↓␈↓ αX␈↓ πλ; the two saved args.␈↓α
␈↓ ↓H␈↓α␈↓ αX(RET)␈↓ πλ␈↓; exit with ␈↓αAC1␈↓ containing the value of ␈↓αj[x;y].
␈↓ ↓H␈↓As␈αyou␈αread␈αthe␈αcode␈α
and␈αas␈αyou␈αstudy␈αits␈αexecution␈α
you␈αshould␈αremember␈αthat␈αthe␈α
addressing␈αin
␈↓ ↓H␈↓the␈α
code␈αis␈α
relative␈α
to␈αthe␈α
top␈αof␈α
the␈α
stack:␈α␈↓α(MOVE 1 -1 P)␈↓␈α
gets␈α
us␈α␈↓αx␈↓␈α
in␈αone␈α
instance␈α
and␈αgets␈α
us␈α␈↓αy␈↓␈α
in
␈↓ ↓H␈↓another, because the top of the stack changes. Here is a picture of the execution of the code:
␈↓ ↓H␈↓␈↓↓6.10␈↓ ε≤A compiler for Simple ␈↓αeval␈↓↓: The Value Stack 317␈↓α
␈↓ ↓H␈↓αAC1: x ; AC2: y␈↓ ∧H␈↓ ¬_␈↓ πλAC1: x ; AC2: y␈↓ HAC1: x ; AC2: y
␈↓ ↓H␈↓α␈↓ αλ␈↓ αX (PUSH P 1)␈↓ ∧H␈↓ ¬_ (PUSH P 2)␈↓ πλ| y␈↓ πX|(MOVE 1 -1 P)␈↓ H| y | (CALL G)
␈↓ ↓H␈↓α␈↓ αλ|␈↓ αX| =>␈↓ ∧H| x␈↓ ¬_| =>␈↓ πλ| x␈↓ πX| =>␈↓ H| x | =>
␈↓ ↓H␈↓αAC1: g[x] ; AC2: ?␈↓ ∧H␈↓ ¬_␈↓ πλAC1: y ; AC2: ?
␈↓ ↓H␈↓α␈↓ αλ␈↓ αX (PUSH P 1)␈↓ ∧H|g[x]␈↓ ¬_|(MOVE 1 -1 P)␈↓ πλ|g[x]␈↓ πX| (PUSHJ P H)
␈↓ ↓H␈↓α␈↓ αλ| y␈↓ αX| =>␈↓ ∧H| y␈↓ ¬_| =>␈↓ πλ| y␈↓ πX| =>
␈↓ ↓H␈↓α␈↓ αλ| x␈↓ αX|␈↓ ∧H| x␈↓ ¬_|␈↓ πλ| x␈↓ πX|
␈↓ ↓H␈↓αAC1: h[y] ; AC2: ?␈↓ ∧HAC1: h[y] ; AC2: h[y]␈↓ πλAC1: g[x] ; AC2: h[y]
␈↓ ↓H␈↓α␈↓ αλ|g[x]␈↓ αX| (MOVE 2 1)␈↓ ∧H|g[x]␈↓ ¬_| (POP P AC1)␈↓ πλ| y |(CALL 2 (E F))
␈↓ ↓H␈↓α␈↓ αλ| y␈↓ αX| =>␈↓ ∧H| y␈↓ ¬_| =>␈↓ πλ| x | =>
␈↓ ↓H␈↓α␈↓ αλ| x␈↓ αX|␈↓ ∧H| x␈↓ ¬_|
␈↓ ↓H␈↓αAC1: f[g[x];h[y]]
␈↓ ↓H␈↓α␈↓ αλ| y␈↓ αX|(SUB P (C 2))␈↓ ∧H␈↓ ¬_␈↓ πλ␈↓ πX (RET) ␈↓return to caller.␈↓α
␈↓ ↓H␈↓α␈↓ αλ| x␈↓ αX| =>␈↓ ∧H␈↓ ¬_=>␈↓ πλ|␈↓ πX|
␈↓ ↓H␈↓␈↓ ∧u␈↓↓6.11 A Compiler for Simple ␈↓αeval␈↓↓␈↓α
␈↓ ↓H␈↓Now␈α
that␈α
we␈α
know␈α
what␈α
the␈α
runtime␈α
code␈α
for␈α
local␈α
variable␈α
references␈α
␈↓↓could␈↓␈α
be,␈α
the␈α
point␈α
now␈αis␈α
to
␈↓ ↓H␈↓get␈αa␈αcompiler␈αto␈αgenerate␈αcode␈αwhich␈α`knows'␈αwhere␈αon␈αthe␈αstack␈αwe␈αcan␈αfind␈αthe␈αvalue␈αof␈αa␈αlocal
␈↓ ↓H␈↓variable␈α∞when␈α∞we␈α∞execute␈α∞that␈α
code.␈α∞ What␈α∞we␈α∞shall␈α∞do␈α
is␈α∞simulate␈α∞the␈α∞behavior␈α∞of␈α∞the␈α
runtime
␈↓ ↓H␈↓stack␈α
while␈αwe␈α
are␈α
compiling␈αthe␈α
code.␈α The␈α
compiler␈α
cannot␈αknow␈α
what␈α
the␈α␈↓↓values␈↓␈α
of␈αthe␈α
variables
␈↓ ↓H␈↓will␈α⊂be␈α∂at␈α⊂run␈α∂time␈α⊂but␈α∂it␈α⊂can␈α⊂know␈α∂␈↓αwhere␈↓␈α⊂to␈α∂find␈α⊂the␈α∂values.␈α⊂ We␈α∂will␈α⊂carry␈α⊂this␈α∂information
␈↓ ↓H␈↓through␈α⊂the␈α⊂compiler␈α⊃in␈α⊂a␈α⊂manner␈α⊃reminiscent␈α⊂of␈α⊂the␈α⊂`association list'␈α⊃symbol␈α⊂table␈α⊂of␈α⊃the␈α⊂␈↓αeval␈↓
␈↓ ↓H␈↓introduced␈αin␈αSection 3.5.␈α Instead␈αof␈αposting␈αthe␈αcurrent␈αvalues␈αin␈αthe␈αstack,␈αthe␈αcompiler␈αwill␈αpost
␈↓ ↓H␈↓information␈α
about␈αthe␈α
positions␈α
of␈αthe␈α
variables␈αrelative␈α
to␈α
the␈αtop␈α
of␈αthe␈α
stack␈α
at␈αthe␈α
time␈αwe␈α
enter
␈↓ ↓H␈↓the␈α⊂function.␈α∂ The␈α⊂variable-position␈α∂list,␈α⊂␈↓αvpl␈↓,␈α⊂contains␈α∂this␈α⊂information.␈α∂ If␈α⊂we␈α∂are␈α⊂to␈α⊂compile␈α∂a
␈↓ ↓H␈↓function with λ-variables, ␈↓α[x;y;z]␈↓ then ␈↓αvpl␈↓ will begin with:
␈↓ ↓H␈↓␈↓ ¬.␈↓α((X . 1), (Y . 2), (Z . 3) ...␈↓
␈↓ ↓H␈↓When␈αwe␈αset␈αup␈α␈↓αvpl␈↓␈αwe␈αalso␈αset␈αthe␈α␈↓↓offset␈↓,␈αcalled␈α␈↓αoff␈↓,␈αto␈αminus␈αthe␈αnumber␈αof␈αarguments␈αadded␈αto
␈↓ ↓H␈↓␈↓αvpl␈↓,␈α∞in␈α∞this␈α∂case␈α∞-3.␈α∞ Now␈α∂if␈α∞we␈α∞come␈α∂across␈α∞a␈α∞reference,␈α∂say␈α∞to␈α∞␈↓αY␈↓,␈α∂while␈α∞compiling␈α∞code,␈α∂we␈α∞use
␈↓ ↓H␈↓␈↓↓318 Dynamic Structure␈↓ +6.11␈↓
␈↓ ↓H␈↓␈↓αcdr[assoc[Y;vpl]]␈↓␈αto␈αretrieve␈α␈↓α2␈↓.␈α The␈αoffset␈αplus␈αthis␈αretrieved␈αvalue␈αgives␈αus␈αthe␈αrelative␈αposition␈αof
␈↓ ↓H␈↓␈↓αY␈↓ in the stack: -3 + 2 = -1. Thus to refer to the location of ␈↓αY␈↓ we use ␈↓α(... -1 P)␈↓.
␈↓ ↓H␈↓What␈α⊂happens␈α⊂as␈α⊂we␈α⊂add␈α⊂elements␈α⊂to␈α⊂the␈α∂stack?␈α⊂ Or␈α⊂to␈α⊂be␈α⊂more␈α⊂precise,␈α⊂what␈α⊂happens␈α⊂as␈α∂we
␈↓ ↓H␈↓generate␈α∞code␈α∞which␈α
when␈α∞executed␈α∞will␈α∞add␈α
elements␈α∞to␈α∞the␈α∞stack?␈α
Clearly␈α∞we␈α∞must␈α∞modify␈α
the
␈↓ ↓H␈↓offset.␈α
If␈αwe␈α
add␈α
one␈αelement,␈α
we␈αwould␈α
set␈α
␈↓αoff␈↓␈αto␈α
-4.␈α Then␈α
to␈α
reference␈α␈↓αY␈↓␈α
now␈αuse␈α
-4␈α
+␈α2␈α
=␈α-2;␈α
that
␈↓ ↓H␈↓is, a reference to ␈↓αY␈↓ is now of the form:
␈↓ ↓H␈↓␈↓ ε∞␈↓α( ......-2 P).␈↓
␈↓ ↓H␈↓But␈α
that's␈α∞right.␈α
␈↓αY␈↓␈α
is␈α∞now␈α
further␈α
down␈α∞in␈α
the␈α
run␈α∞time␈α
stack.␈α
Thus␈α∞the␈α
`symbol␈α
table'␈α∞is␈α
really
␈↓ ↓H␈↓defined␈αby␈α␈↓αoff␈↓␈αplus␈αthe␈αcurrent␈α␈↓αvpl␈↓.␈αHere's␈αa␈αsketch␈αof␈αthe␈αproposed␈α␈↓αcompexp␈↓␈αin␈αits␈αperformance␈αof
␈↓ ↓H␈↓local variable recognition.
␈↓ ↓H␈↓α␈↓ ∧'islocalvar[exp] → list[mkvar[1;loc[exp;off;vpl]]]
␈↓ ↓H␈↓α␈↓where:␈↓α
␈↓ ↓H␈↓α␈↓ ∧%loc <= λ[[x;off;vpl] plus[off;cdr[assoc[x;vpl]]]]
␈↓ ↓H␈↓α␈↓and,␈↓α
␈↓ ↓H␈↓α␈↓ ∧3mkvar <= λ[[ac;mem] list[MOVE;ac;mem;P]]
␈↓ ↓H␈↓Next,␈α
when␈α
will␈α
the␈α
compiler␈α
make␈α
modifications␈α∞to␈α
the␈α
top␈α
of␈α
the␈α
stack?␈α
We␈α
push␈α∞new␈α
elements
␈↓ ↓H␈↓when␈α∂we␈α∂are␈α∞compiling␈α∂the␈α∂arguments␈α∞to␈α∂a␈α∂function␈α∞call.␈α∂We␈α∂know␈α∞that␈α∂␈↓αcomplis␈↓␈α∂is␈α∂the␈α∞function
␈↓ ↓H␈↓which␈αcompiles␈αthe␈αargument␈αlist.␈α Thus␈αour␈αnew␈α␈↓αcomplis␈↓␈αhad␈αbetter␈αknow␈αabout␈α␈↓αoff␈↓␈αand␈α␈↓αvpl␈↓,␈αand
␈↓ ↓H␈↓since ␈↓αcomplis␈↓ changes the state of the stack, then it had better change ␈↓αoff␈↓ appropriately:
␈↓ ↓H␈↓αcomplis <= λ[[u;off;vpl]␈↓ ∧_[null [u] → ( );
␈↓ ↓H␈↓α␈↓ ∧_ null[rest[u]] → compexp[first[u];off; vpl];
␈↓ ↓H␈↓α␈↓ ∧_ ␈↓
t␈↓α → append␈↓ ¬8[compexp [first[u]; off; vpl];
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ¬8 list[mkalloc[1]];
␈↓ ↓H␈↓α␈↓ ∧_␈↓ ¬8 complis [rest[u]; sub1[off]; vpl]]]]
␈↓ ↓H␈↓Notice␈α
that␈α
␈↓αcomplis␈↓␈αcompiles␈α
the␈α
arguments␈αfrom␈α
left␈α
to␈α
right,␈αfollowing␈α
each␈α
with␈α␈↓α(PUSH P 1)␈↓␈α
and
␈↓ ↓H␈↓recurring with a new offset reflecting the effect of the ␈↓αPUSH␈↓. This function is analogous to ␈↓αevlis␈↓.
␈↓ ↓H␈↓Here's a brief description of the parts of the new compiler␈↓π 209␈↓.
␈↓ ↓H␈↓␈↓αcompile[fn;vars;exp]:␈α⊂fn␈↓␈α⊂is␈α⊂the␈α⊂name␈α∂of␈α⊂the␈α⊂function␈α⊂to␈α⊂be␈α∂compiled.␈α⊂␈↓αvars␈↓␈α⊂is␈α⊂the␈α⊂list␈α⊂of␈α∂lambda
␈↓ ↓H␈↓␈↓ βXvariables. ␈↓αexp␈↓ is the lambda-body.
␈↓ ↓H␈↓␈↓αprup[vars;n]: vars␈↓ is a lambda list, ␈↓αn␈↓ is an integer. ␈↓αprup␈↓ builds a variable-position list.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 209␈↓␈α
This␈α
compiler␈α
was␈αadapted␈α
from␈α
one␈α
written␈αby␈α
J. McCarthy␈α
([McC 76]),␈α
and␈α
proved␈αcorrect
␈↓ ↓H␈↓by R. London ([Lon 71]) and M. Newey ([New 75]).
␈↓ ↓H␈↓␈↓↓6.11␈↓ λ¬A Compiler for Simple ␈↓αeval␈↓↓ 319␈↓α
␈↓ ↓H␈↓␈↓αcompexp[exp;off;vpl]␈↓:␈α
This␈αfunction␈α
generates␈α
the␈αcode␈α
for␈α
constants␈αand␈α
for␈α
references␈αto␈α
variables.
␈↓ ↓H␈↓␈↓ βxIf␈α
the␈α
variable␈α
is␈α
local,␈α
a␈α
simple␈α
␈↓αsend␈↓␈α
is␈α
generated,␈α
otherwise␈α
a␈α
call␈αon␈α
␈↓αlookup␈↓
␈↓ ↓H␈↓␈↓ βxresults.␈α∀ If␈α∀a␈α∀conditional␈α∀expression␈α∀is␈α∀recognized,␈α∀␈↓αcomcond␈↓␈α∀is␈α∀called␈α∀to
␈↓ ↓H␈↓␈↓ βxproduce␈αthe␈αcode.␈α
If␈α␈↓αexp␈↓␈αdoes␈α
not␈αfit␈αone␈αof␈α
these␈αcategories,␈αit␈α
is␈αassumed
␈↓ ↓H␈↓␈↓ βxto␈α∪be␈α∪an␈α∀application␈α∪of␈α∪a␈α∪call-by-value␈α∀function.␈α∪ In␈α∪this␈α∀case,␈α∪␈↓αcomplis␈↓
␈↓ ↓H␈↓␈↓ βxcompiles␈αthe␈αargument␈αlist,␈αleaving␈αthe␈αarguments␈αin␈αthe␈αstack;␈α␈↓αloadac␈↓␈αloads
␈↓ ↓H␈↓␈↓ βxthe␈α⊂appropriate␈α⊂␈↓αAC␈↓'s.␈α⊂ and␈α⊂then␈α⊂we␈α∂generate␈α⊂a␈α⊂call␈α⊂on␈α⊂the␈α⊂function,␈α∂and
␈↓ ↓H␈↓␈↓ βxfinally generate the ␈↓αSUB␈↓ to synchronize the stack.
␈↓ ↓H␈↓␈↓αcomcond[u;glob;off;vpl]␈↓:␈α
this␈α
compiles␈α
the␈α
body␈α
of␈α∞conditional␈α
expressions.␈α
␈↓αu␈↓␈α
is␈α
the␈α
p␈↓βi␈↓ - e␈↓βi␈↓␈α∞list;␈α
␈↓αglob␈↓
␈↓ ↓H␈↓␈↓ ∧λwill␈αbe␈αbound␈αto␈αa␈αgenerated␈αsymbol␈αname;␈α␈↓αoff␈↓␈αand␈α␈↓αvpl␈↓␈αwill␈αalways␈αbe␈αthe
␈↓ ↓H␈↓␈↓ ∧λoffset and the variable-position list.
␈↓ ↓H␈↓Fortified by the previous ␈↓αcompile␈↓ functions and this introduction the new ␈↓αcompile␈↓ should be clear.
␈↓ ↓H␈↓αcompile <= λ[␈↓ αx[fn;vars;exp]
␈↓ ↓H␈↓α␈↓ αxλ[[n] append[␈↓ ∧8mkprolog[fn;n];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧8compexp[exp; -n; prup[vars;1]];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧8mkepilog[n]]]
␈↓ ↓H␈↓α␈↓ αx [length[vars]] ]
␈↓ ↓H␈↓αmkprolog <= λ[[f;n] concat[list[LAP;f;SUBR];mkpushs[n;1]]]
␈↓ ↓H␈↓αmkpushs <= λ[[n;m][␈↓ βXlessp[n;m] → ( );
␈↓ ↓H␈↓α␈↓ βX␈↓
t␈↓α → concat[mkalloc[m]; mkpushs[n;add1[m]]]]]
␈↓ ↓H␈↓αmkepilog <= λ[[n] list[mksync[n];mkret[]]]
␈↓ ↓H␈↓αmksync <=λ[[n] list[SUB;P;list[C;n]]]
␈↓ ↓H␈↓αmkret <=λ[[] (RET)]
␈↓ ↓H␈↓αprup <= λ[[vars;n][␈↓ βHnull[vars] → ( );
␈↓ ↓H␈↓α␈↓ βH␈↓
t␈↓α → concat[cons[first[vars]; n];prup[rest[vars];add1[n]]]]]
␈↓ ↓H␈↓␈↓↓320 Dynamic Structure␈↓ +6.11␈↓
␈↓ ↓H␈↓αcompexp <= λ[[exp;off;vpl]␈↓ ∧([isconst[exp] → list[mkconst[1;exp]];
␈↓ ↓H␈↓α␈↓ ∧( islocalvar[exp] → list [mkvar[1;loc[exp;off;vpl]]];
␈↓ ↓H␈↓α␈↓ ∧( isnonlocal[exp] → list[mklookup[exp]];
␈↓ ↓H␈↓α␈↓ ∧( iscond[exp] → comcond[args␈↓βc␈↓α[exp];gensym[ ];off; vpl];
␈↓ ↓H␈↓α␈↓ ∧( isfun+args[exp] →␈↓ ε(λ[[z] compapply[␈↓ λλfunc[exp];
␈↓ ↓H␈↓α␈↓ ∧(␈↓ ε(␈↓ λλcomplis[z;off;vpl];
␈↓ ↓H␈↓α␈↓ ∧(␈↓ ε(␈↓ λλlength[z]]
␈↓ ↓H␈↓α␈↓ ∧(␈↓ ε( [arglist[exp]] ]]
␈↓ ↓H␈↓␈↓αcompapply␈↓ is found on page 302.
␈↓ ↓H␈↓αcomcond <= λ[[u;glob;off;vpl][␈↓ ∧Hnull[u] → list[mkerror[ ];glob];
␈↓ ↓H␈↓α␈↓ ∧H␈↓
t␈↓α → append[␈↓ ¬hcomclause[first[u]; gensym[];glob;off;vpl];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬hcomcond[rest[u]; glob;off;vpl] ]]
␈↓ ↓H␈↓αcomclause <=λ[[p;loc;glob;off;vpl]append[␈↓ ¬Xcompexp[ante[p];off;vpl];
␈↓ ↓H␈↓α␈↓ ¬Xlist[mkjumpf[loc]];
␈↓ ↓H␈↓α␈↓ ¬Xcompexp[conseq[p];off;vpl];
␈↓ ↓H␈↓α␈↓ ¬Xlist[mkjump[glob];loc]]]
␈↓ ↓H␈↓Here␈α⊂is␈α⊂a␈α⊂partial␈α⊂sketch␈α⊂of␈α⊂␈↓αcompile␈↓␈α∂operating␈α⊂on␈α⊂␈↓αj␈α⊂<=␈α⊂λ[[x;y]f[g[x];h[y]]]␈↓.␈α⊂ Compare␈α⊂the␈α⊂code␈α∂it
␈↓ ↓H␈↓generates with the code we saw on page 316.
␈↓ ↓H␈↓αcompile[J;(X Y);(F (G X) (H Y))]
␈↓ ↓H␈↓α␈↓gives:␈↓α
␈↓ ↓H␈↓α␈↓ αXappend␈↓ βH[((LAP J SUBR));
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (PUSH P 1)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (PUSH P 2)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH compexp[(F (G X) (H Y));-2;prup[(X Y);1]];
␈↓ ↓H␈↓α␈↓ αX␈↓ βH ((SUB P (C 2))
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (RET))] ␈↓
␈↓ ↓H␈↓where:
␈↓ ↓H␈↓␈↓ ∧$␈↓αprup[(X Y);1]␈↓ gives ␈↓α((X . 1) (Y . 2))␈↓.
␈↓ ↓H␈↓␈↓↓6.11␈↓ λ¬A Compiler for Simple ␈↓αeval␈↓↓ 321␈↓α
␈↓ ↓H␈↓␈↓αcompexp[(F (G X) (H Y));-2;((X . 1) (Y . 2))]␈↓
␈↓ ↓H␈↓results in:
␈↓ ↓H␈↓α␈↓ αXappend␈↓ βH[complis[((G X) (H Y));-2;((X . 1) (Y . 2))];
␈↓ ↓H␈↓α␈↓ αX␈↓ βH mklink[2];
␈↓ ↓H␈↓α␈↓ αX␈↓ βH ((CALL F))]
␈↓ ↓H␈↓α␈↓and ␈↓αmklink[2]␈↓ evaluates to: ␈↓α((MOVE 2 1) (POP P 1))␈↓.
␈↓ ↓H␈↓Thus the code we're getting looks like:
␈↓ ↓H␈↓α␈↓ αX␈↓ βH((LAP J SUBR)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (PUSH P 1)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (PUSH P 2)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH complis[((G X) (H Y)); -2; ((X . 1) (Y . 2))]
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (MOVE 2 1)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (POP P 1)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (CALL F)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (SUB P (C 2))
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (RET) )
␈↓ ↓H␈↓αcomplis␈↓ is interesting since it actually uses the ␈↓αvpl␈↓ we have been carrying along. It gives rise to:
␈↓ ↓H␈↓α␈↓ αXappend␈↓ βH[compexp[(G X);-2;((X . 1) (Y . 2))];
␈↓ ↓H␈↓α␈↓ αX␈↓ βH ((PUSH P 1));
␈↓ ↓H␈↓α␈↓ αX␈↓ βH complis[((H Y));-3;((X . 1) (Y . 2))]]
␈↓ ↓H␈↓α␈↓and the ␈↓αcompexp␈↓ computation involves, in part:
␈↓ ↓H␈↓α␈↓ αXappend[complis[(X);-2;((X . 1) (Y . 2))];
␈↓ ↓H␈↓α␈↓ αX␈↓ βH ((CALL G))]
␈↓ ↓H␈↓α␈↓Finally this ␈↓αcomplis␈↓ generates the long awaited variable reference using:
␈↓ ↓H␈↓␈↓αcompexp[X;-2;((X . 1) (Y . 2))] ␈↓giving, ␈↓α((MOVE 1 -1 P))␈↓.
␈↓ ↓H␈↓␈↓↓322 Dynamic Structure␈↓ +6.11␈↓
␈↓ ↓H␈↓So our code is:
␈↓ ↓H␈↓α␈↓ αX␈↓ βH((LAP J SUBR)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (PUSH P 1)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (PUSH P 2)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (MOVE 1 -1 P)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (CALL G)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (PUSH P 1)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH complis[((H Y)); -3; ((X . 1) (Y . 2))]
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (MOVE 2 1)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (POP P 1)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (CALL F)
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (SUB P (C 2))
␈↓ ↓H␈↓α␈↓ αX␈↓ βH (RET) )␈↓
␈↓ ↓H␈↓Notice that the offset is different within the call:
␈↓ ↓H␈↓␈↓ ∧c␈↓α complis[((H Y));-3;((X . 1) (Y . 2))].␈↓
␈↓ ↓H␈↓But that is as it should be: there is an extra value on the stack now.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓ Complete the code generation for the above example.
␈↓ ↓H␈↓␈↓↓2.␈↓ Extend the compiling algorithm to recognize anonymous λ-expressions.
␈↓ ↓H␈↓␈↓ ¬↔␈↓↓6.12 Efficient Compilation␈↓
␈↓ ↓H␈↓We␈α⊂have␈α⊃discussed␈α⊂compilation␈α⊂at␈α⊃two␈α⊂different␈α⊃levels:␈α⊂we␈α⊂can␈α⊃translate␈α⊂LISP␈α⊃expressions␈α⊂into
␈↓ ↓H␈↓sequences␈αof␈αthe␈αLISP␈αcontrol␈αprimitives␈αof␈αSection 6.2;␈αor␈αwe␈αcan␈αtranslate␈αinto␈αthe␈αinstructions␈αof
␈↓ ↓H␈↓the␈α⊂␈↓ SM␈↓␈α⊂machine␈α⊂of␈α⊂Section 6.3.␈α⊂We␈α⊃conceptualized␈α⊂the␈α⊂compilers␈α⊂in␈α⊂terms␈α⊂of␈α⊂higher␈α⊃level,␈α⊂but
␈↓ ↓H␈↓biased␈α⊃many␈α⊃of␈α⊃our␈α⊃choices␈α⊃towards␈α⊃implementations␈α⊂in␈α⊃terms␈α⊃of␈α⊃the␈α⊃␈↓ SM␈↓␈α⊃instruction␈α⊃set.␈α⊂Our
␈↓ ↓H␈↓choices influenced the efficiency of the resulting compiler.
␈↓ ↓H␈↓We␈αshould␈αfirst␈αclarify␈αwhat␈αwe␈αmean␈αby␈αefficiency␈αin␈αthis␈αcontext.␈α If␈αthe␈αcompiler␈αproduces␈αcode
␈↓ ↓H␈↓for␈α
the␈α
LISP␈α
primitives␈α
and␈α
then␈α
we␈α
encode␈αthe␈α
LISP␈α
primitives␈α
in␈α
terms␈α
of␈α
the␈α
␈↓ SM␈↓␈αinstruction␈α
set,
␈↓ ↓H␈↓then␈α
we␈α
get␈α
a␈α
simple␈α
compiler␈α
which␈α
tends␈α
to␈α
produce␈α
inefficient␈α
code;␈α
inefficent,␈α
in␈α
terms␈α
of␈α
the
␈↓ ↓H␈↓␈↓↓6.12␈↓ λKEfficient Compilation 323␈↓
␈↓ ↓H␈↓␈↓ SM␈↓␈αmachine,␈αnot␈αin␈α
terms␈αof␈αthe␈αLISP␈α
primitives.␈αSuch␈αa␈αcompiler␈α
would␈αbe␈αefficient␈αin␈α
terms␈αof
␈↓ ↓H␈↓compilation time and might suffice for debugging runs or student projects.
␈↓ ↓H␈↓More␈αlikely,␈αefficient␈αcompilation␈αis␈αtaken␈αto␈αmean␈αproduction␈αof␈αcode␈αwhich␈αwe␈αcould␈αexpect␈αfrom
␈↓ ↓H␈↓a␈α∪reasonably␈α∪bright␈α∀machine-language␈α∪programmer.␈α∪ It␈α∪should␈α∀run␈α∪reasonably␈α∪fast,␈α∀not␈α∪have
␈↓ ↓H␈↓obviously␈α∞redundant␈α∞instructions,␈α∞and␈α∞not␈α∞take␈α∞too␈α∂much␈α∞space␈α∞in␈α∞the␈α∞machine.␈α∞It␈α∞is␈α∂this␈α∞second
␈↓ ↓H␈↓interpretation␈αof␈α
efficiency␈αwhich␈α
we␈αshall␈αuse.␈α
In␈αthis␈α
interpretation␈αwe␈α
don't␈αsimply␈αimplement␈α
the
␈↓ ↓H␈↓LISP␈α∞primitives,␈α
but␈α∞take␈α∞a␈α
more␈α∞global␈α
view␈α∞of␈α∞the␈α
underlying␈α∞machine.␈α
We␈α∞take␈α∞advantage␈α
of
␈↓ ↓H␈↓more␈αof␈αthe␈αhardware␈αfeatures,␈αincorporating␈αthem␈αdeeper␈αinto␈αthe␈αstructure␈αof␈αthe␈αcompiler.␈α This
␈↓ ↓H␈↓process␈α∃is␈α∃called␈α∃optimization.␈α∃ Optimization␈α∃defies␈α∃the␈α∃mismatch␈α∃between␈α∃the␈α∀programming
␈↓ ↓H␈↓language␈α⊃and␈α⊃the␈α⊃hardware␈α⊂machine.␈α⊃ The␈α⊃result␈α⊃is␈α⊃a␈α⊂compiler␈α⊃which␈α⊃is␈α⊃much␈α⊃more␈α⊂machine
␈↓ ↓H␈↓dependent, requires more processing time, but produces much better code for that specific machine.
␈↓ ↓H␈↓Examination␈α⊗of␈α⊗the␈α⊗compilation␈α⊗of␈α↔even␈α⊗the␈α⊗most␈α⊗simple␈α⊗function␈α⊗suggests␈α↔many␈α⊗possible
␈↓ ↓H␈↓improvements,␈α∪given␈α∪the␈α∪␈↓ SM␈↓␈α∪machine.␈α∪ A␈α∪major␈α∪inefficiency␈α∪occurs␈α∪in␈α∪saving␈α∀and␈α∪restoring
␈↓ ↓H␈↓quantities␈α∩on␈α∩the␈α∩stack.␈α⊃This␈α∩is␈α∩a␈α∩symptom␈α⊃of␈α∩a␈α∩more␈α∩serious␈α⊃disease:␈α∩the␈α∩compiler␈α∩does␈α⊃not
␈↓ ↓H␈↓remember␈α∞what␈α∞will␈α∞be␈α∂in␈α∞the␈α∞ACs␈α∞at␈α∂run-time.␈α∞Since␈α∞we␈α∞are␈α∂assuming␈α∞that␈α∞the␈α∞arguments␈α∂to␈α∞a
␈↓ ↓H␈↓function␈αcall␈αare␈αto␈αbe␈αpassed␈αthrough␈αthe␈α␈↓αAC␈↓'s,␈αand␈αsince␈αit␈αis␈αexpensive␈αto␈αsave␈αand␈αrestore␈αthese
␈↓ ↓H␈↓registers,␈α
we␈α∞should␈α
make␈α
a␈α∞concerted␈α
effort␈α
to␈α∞remember␈α
what␈α
quantities␈α∞are␈α
in␈α
which␈α∞ACs␈α
and
␈↓ ↓H␈↓not␈α
reload␈αthem␈α
unnecessarily.␈αBut␈α
note␈αthat␈α
this␈αoptimization␈α
is␈αdependent␈α
on␈αthe␈α
hardware␈αof␈α
our
␈↓ ↓H␈↓machine; if we had only one ␈↓αAC␈↓, the trick would not be applicable.
␈↓ ↓H␈↓␈↓ ∧P␈↓↓6.13 Efficiency: Primitive Operations␈↓
␈↓ ↓H␈↓First we should be able to generate references to constants into ␈↓αAC␈↓'s other that ␈↓αAC1␈↓.
␈↓ ↓H␈↓For example, the call on ␈↓αf[1;A]␈↓ should be generated as:
␈↓ ↓H␈↓α␈↓ ¬H(MOVEI 1 1)
␈↓ ↓H␈↓α␈↓ ¬H(MOVEI 2 (QUOTE A))
␈↓ ↓H␈↓α␈↓ ¬H(CALL F)
␈↓ ↓H␈↓There is no reason to save constants in the stack.
␈↓ ↓H␈↓We␈αshould␈αalso␈αexpect␈αthat␈αthe␈αLISP␈αprimitive␈αoperations,␈α␈↓αcar,␈αcdr,␈αcons,␈αeq,␈↓␈αand␈α␈↓αatom␈↓␈αshould␈αoccur
␈↓ ↓H␈↓rather␈αfrequently␈αin␈αcompiled␈αcode;␈αand␈αwe␈αshould␈αexpect␈αthat␈αa␈αreasonable␈αcompiler␈αbe␈αcognizant
␈↓ ↓H␈↓of␈α⊂their␈α⊃existence␈α⊂and␈α⊂compile␈α⊃more␈α⊂efficient␈α⊂code␈α⊃for␈α⊂their␈α⊂execution.␈α⊃ In␈α⊂this␈α⊂section␈α⊃we␈α⊂will
␈↓ ↓H␈↓enlarge␈α⊗the␈α∃instruction␈α⊗set␈α∃of␈α⊗our␈α∃machine,␈α⊗adding␈α∃plausible␈α⊗operations␈α∃for␈α⊗some␈α⊗of␈α∃these
␈↓ ↓H␈↓primitives␈↓π 210␈↓.␈αIn␈αthe␈αdescription␈αof␈α
these␈αnew␈αinstructions␈α␈↓αac␈↓␈αwill␈α
always␈αrefer␈αto␈αan␈α␈↓αAC␈↓-register;␈α
␈↓αloc␈↓
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 210␈↓␈α
Some␈α
of␈α∞these␈α
instuctions␈α
exist␈α∞on␈α
the␈α
PDP-10.␈α
HLRZ␈α∞and␈α
HRRZ␈α
are␈α∞used␈α
for␈α
␈↓αcar␈↓␈α∞and␈α
␈↓αcdr␈↓,
␈↓ ↓H␈↓respectively;␈αand␈α
the␈αversion␈αof␈α
the␈αPDP-6␈αwhich␈α
was␈αdelivered␈αto␈α
Stanford␈αhad␈αa␈α
hardware␈α␈↓αcons␈↓
␈↓ ↓H␈↓operation.
␈↓ ↓H␈↓␈↓↓324 Dynamic Structure␈↓ )6.13␈↓
␈↓ ↓H␈↓will be either an ␈↓αAC␈↓ or a memory location, and ␈↓αmem␈↓ will be reserved for memory references only.
␈↓ ↓H␈↓␈↓αCAR␈↓␈α∂is␈α∞an␈α∂instruction,␈α∞taking␈α∂two␈α∞arguments:␈α∂an␈α∞␈↓αac␈↓␈α∂and␈α∞a␈α∂␈↓αloc␈↓␈α∞respectively.␈α∂The␈α∞␈↓αcar␈↓␈α∂operation␈α∞is
␈↓ ↓H␈↓performed␈α
from␈α␈↓αloc␈↓␈α
to␈α␈↓αac␈↓.␈α
For␈αexample␈α
when␈αcompiling␈α
the␈αcall,␈α
␈↓αf[1;car[x]]␈↓,␈αwe␈α
want␈αto␈α
get␈α␈↓αcar[x]␈↓␈α
in
␈↓ ↓H␈↓␈↓αAC2␈↓. If ␈↓αx␈↓ were in -␈↓α5 P␈↓ then we could accomplish our loading directly by ␈↓α(CAR 2 -5 P)␈↓ instead of:
␈↓ ↓H␈↓α␈↓ ¬H(MOVE 1 -5 P)
␈↓ ↓H␈↓α␈↓ ¬H(CALL CAR)
␈↓ ↓H␈↓α␈↓ ¬H(MOVE 2 1)
␈↓ ↓H␈↓We␈α∞can␈α∞also␈α∞exploit␈α∂the␈α∞fact␈α∞that␈α∞the␈α∂second␈α∞argument␈α∞to␈α∞␈↓αCAR␈↓␈α∞is␈α∂a␈α∞␈↓αloc␈↓:␈α∞the␈α∞second␈α∂argument␈α∞to
␈↓ ↓H␈↓␈↓αf[1;car[car[x]]]␈↓ could have been compiled as:
␈↓ ↓H␈↓α␈↓ ¬H(CAR 2 -5 P)
␈↓ ↓H␈↓α␈↓ ¬H(CAR 2 2)
␈↓ ↓H␈↓We␈αwill␈αassume␈αthe␈αexistence␈αof␈αan␈αanalogous␈α␈↓αCDR␈↓␈αinstruction.␈αWith␈αthese␈αtwo␈αinstructions␈αwe␈αcan
␈↓ ↓H␈↓significantly improve the code for ␈↓αcar-cdr␈↓-chains.
␈↓ ↓H␈↓Another source of efficiency is available to us. Consider the clause:
␈↓ ↓H␈↓α␈↓ ¬i[eq[x;A] → B; ...]
␈↓ ↓H␈↓Assuming that ␈↓αx␈↓ were on the top of the stack, our current compiler would generate:
␈↓ ↓H␈↓α␈↓ ¬H (MOVE 1 0 P)
␈↓ ↓H␈↓α␈↓ ¬H (MOVEI 2 (QUOTE A))
␈↓ ↓H␈↓α␈↓ ¬H (CALL EQ)
␈↓ ↓H␈↓α␈↓ ¬H (JUMPF 1 L1)
␈↓ ↓H␈↓α␈↓ ¬H (MOVEI 1 (QUOTE B))
␈↓ ↓H␈↓α␈↓ ¬H (JUMP LOUT)
␈↓ ↓H␈↓α␈↓ ¬HL1 ...
␈↓ ↓H␈↓The␈αuse␈αof␈αpredicates␈αin␈αthis␈αcontext␈αdoes␈αnot␈αrequire␈αconstruction␈αof␈αthe␈αconstants␈α␈↓
t␈↓␈αand␈α␈↓
f␈↓.␈αAll␈αwe
␈↓ ↓H␈↓need to do is implement the ␈↓αeq␈↓ test as a jump to one of two locations.
␈↓ ↓H␈↓We␈α
will␈α
introduce␈α∞an␈α
instruction␈α
␈↓αCAME␈↓␈α
taking␈α∞two␈α
arguments;␈α
first,␈α
an␈α∞␈↓αac␈↓␈α
and␈α
the␈α
second,␈α∞a␈α
␈↓αloc␈↓.
␈↓ ↓H␈↓␈↓αCAME␈↓␈α⊃compares␈α⊃the␈α∩contents␈α⊃of␈α⊃the␈α∩two␈α⊃arguments,␈α⊃and␈α∩if␈α⊃they␈α⊃are␈α∩equal,␈α⊃it␈α⊃skips␈α∩the␈α⊃next
␈↓ ↓H␈↓instruction.
␈↓ ↓H␈↓Thus the above example could be compiled as:
␈↓ ↓H␈↓α␈↓ ¬H (MOVEI 1 (QUOTE A))
␈↓ ↓H␈↓α␈↓ ¬H (CAME 1 0 P)
␈↓ ↓H␈↓α␈↓ ¬H (JUMP L1)
␈↓ ↓H␈↓α␈↓ ¬H (MOVEI 1 (QUOTE B))
␈↓ ↓H␈↓α␈↓ ¬H (JUMP LOUT)
␈↓ ↓H␈↓α␈↓ ¬HL1 ...
␈↓ ↓H␈↓␈↓↓6.13␈↓ π<Efficiency: Primitive Operations 325␈↓
␈↓ ↓H␈↓Notice␈α⊃that␈α⊃we␈α⊃have␈α⊃added␈α⊃an␈α⊃extra␈α⊃piece␈α⊃of␈α⊃knowledge␈α⊃to␈α⊃the␈α⊃compiler;␈α⊃it␈α⊃knows␈α⊃that␈α∩␈↓αeq␈↓␈α⊃is
␈↓ ↓H␈↓commutative␈α∂in␈α∞this␈α∂instance␈↓π 211␈↓.␈α∞We␈α∂still␈α∂require␈α∞some␈α∂artifacts␈α∞in␈α∂the␈α∞compiler␈α∂to␈α∂generate␈α∞full
␈↓ ↓H␈↓procedure␈α
calls␈α
on␈α
predicates␈α
particularly␈α
since␈α
predicates␈α
may␈α
return␈α
values␈α
other␈α
than␈α
␈↓
t␈↓␈α
and␈α␈↓
f␈↓.␈α
But
␈↓ ↓H␈↓in many instances, particularly within ␈↓αcompcond␈↓, we can expect to generate tighter code.
␈↓ ↓H␈↓␈↓ ∧c␈↓↓6.14 Efficiency: Calling Sequences␈↓
␈↓ ↓H␈↓We␈αwant␈αto␈αintegrate␈αthe␈αnew␈αcompiling␈αtechniques␈αinto␈αour␈αcompiler.␈αSince␈αLISP␈αdepends␈αheavily
␈↓ ↓H␈↓on␈α⊂procedure␈α⊃calls,␈α⊂the␈α⊂computation␈α⊃of␈α⊂parameter␈α⊂lists␈α⊃and␈α⊂procedure␈α⊂calls␈α⊃is␈α⊂an␈α⊂area␈α⊃of␈α⊂great
␈↓ ↓H␈↓concern to the designer of a LISP compiler.
␈↓ ↓H␈↓Here is the code which the current compiler will produce for the expression ␈↓αf[1;g[3]; car[x]]␈↓:
␈↓ ↓H␈↓α␈↓ ¬H(MOVEI 1 1)
␈↓ ↓H␈↓α␈↓ ¬H(PUSH P 1)
␈↓ ↓H␈↓α␈↓ ¬H(MOVEI 1 3)
␈↓ ↓H␈↓α␈↓ ¬H(CALL G)
␈↓ ↓H␈↓α␈↓ ¬H(PUSH P 1)
␈↓ ↓H␈↓α␈↓ ¬H(MOVE 1 -2 P)
␈↓ ↓H␈↓α␈↓ ¬H(CALL CAR)
␈↓ ↓H␈↓α␈↓ ¬H(MOVE 3 1)
␈↓ ↓H␈↓α␈↓ ¬H(POP P 2)
␈↓ ↓H␈↓α␈↓ ¬H(POP P 1)
␈↓ ↓H␈↓α␈↓ ¬H(CALL F)
␈↓ ↓H␈↓By way of motivation and introduction, here is what our next compiler does for the same call:
␈↓ ↓H␈↓α␈↓ ¬H(MOVEI 1 3)
␈↓ ↓H␈↓α␈↓ ¬H(CALL G)
␈↓ ↓H␈↓α␈↓ ¬H(MOVE 2 1)
␈↓ ↓H␈↓α␈↓ ¬H(CAR 3 0 P)
␈↓ ↓H␈↓α␈↓ ¬H(MOVEI 1 1)
␈↓ ↓H␈↓α␈↓ ¬H(CALL F)
␈↓ ↓H␈↓Examination␈α
of␈α∞the␈α
code␈α∞shows␈α
the␈α∞results␈α
of␈α
several␈α∞optimization␈α
techniques.␈α∞ We␈α
are␈α∞using␈α
the
␈↓ ↓H␈↓␈↓αCAR␈↓␈αinstruction␈αof␈α
the␈αlast␈αsection.␈α
We␈αare␈αalso␈α
doing␈αoperations␈αinto␈α
␈↓αAC␈↓'s␈αother␈αthan␈α
␈↓αAC1␈↓.␈αThis
␈↓ ↓H␈↓allows us to remove some of the obnoxious ␈↓αPUSH-POP␈↓ sequences.
␈↓ ↓H␈↓The␈αmajor␈αmodification␈αinvolves␈αan␈αanalysis␈α
of␈αthe␈αarguments␈αbeing␈αcompiled␈αfor␈αa␈α
function␈αcall.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 211␈↓␈αIf␈αthere␈αare␈αside-effects␈αin␈αthe␈αcomputation␈αof␈αthe␈αarguments,␈αthe␈αorder␈αcan␈αmake␈αa␈αdifference.
␈↓ ↓H␈↓However unless explicitly stated our compilers do not have to consider side-effects.
␈↓ ↓H␈↓␈↓↓326 Dynamic Structure␈↓ &6.14␈↓
␈↓ ↓H␈↓Much␈α∪of␈α∀LISP's␈α∪activity␈α∀involves␈α∪function␈α∪calls.␈α∀Much␈α∪of␈α∀the␈α∪current␈α∀compiler's␈α∪inefficiency
␈↓ ↓H␈↓involves␈α⊂generation␈α⊂of␈α⊂arguments␈α⊂to␈α⊂those␈α⊃calls.␈α⊂ This␈α⊂is␈α⊂a␈α⊂bad␈α⊂combination.␈α⊂ Thus␈α⊃we␈α⊂should
␈↓ ↓H␈↓concentrate␈α
some␈α
effort␈αon␈α
this␈α
area␈α
of␈αthe␈α
compiler.␈α
That␈α
part␈αis␈α
␈↓αcomplis␈↓.␈α
Within␈α
our␈αnew␈α
␈↓αcomplis␈↓
␈↓ ↓H␈↓we␈α∂will␈α∂divide␈α∂the␈α⊂arguments␈α∂into␈α∂two␈α∂classes: trivial␈α∂and␈α⊂complex.␈α∂ Since␈α∂most␈α∂of␈α∂our␈α⊂worry␈α∂is
␈↓ ↓H␈↓about␈αthe␈αoptimization␈α
of␈αthe␈α␈↓αAC␈↓'s,␈α
we␈αwill␈αmake␈α␈↓αcomplis␈↓␈α
the␈αmajor␈αstate␈α
of␈αthe␈αcompiler.␈α
We␈αcan
␈↓ ↓H␈↓define ␈↓αcompexp␈↓ as:
␈↓ ↓H␈↓α␈↓ β|compexp <= λ[[exp;vpl;off] complis[list[exp];vpl;off]]
␈↓ ↓H␈↓␈↓αcomplis␈↓␈α
is␈α
the␈α
natural␈α
place␈αto␈α
deal␈α
with␈α
register␈α
allocation␈αsince␈α
it␈α
is␈α
responsible␈α
for␈αthe␈α
compilation
␈↓ ↓H␈↓of␈α∞the␈α∞actual␈α∞parameters.␈α∞The␈α
alternative␈α∞would␈α∞be␈α∞to␈α∞pass␈α
the␈α∞␈↓αAC␈↓␈α∞destination␈α∞to␈α∞␈↓αcompexp␈↓.␈α
That
␈↓ ↓H␈↓scheme␈α∞becomes␈α∞quite␈α∞complex␈α∞if␈α∞dealt␈α∞with␈α∞consistently.␈α∞So␈α∞␈↓αcomplis␈↓␈α∞becomes␈α∞the␈α∂kernel␈α∞function
␈↓ ↓H␈↓and must examine each argument to a function call.
␈↓ ↓H␈↓Trivial␈αarguments␈αare␈αthose␈α
which␈αneed␈αmake␈αno␈αdemands␈α
on␈αthe␈αruntime␈αstack;␈α
the␈αcomputation
␈↓ ↓H␈↓they␈αentail␈αcan␈αall␈αbe␈αdone␈αin␈αthe␈α␈↓αAC␈↓␈αregisters.␈αThus␈αthe␈αcode␈αthat␈αthe␈αcompiler␈αgenerates␈αneed␈αnot
␈↓ ↓H␈↓involve␈α∞␈↓αPUSH-POP␈↓␈α∞sequences.␈α∞ For␈α∞example,␈α∞references␈α∞to␈α∞constants␈α∞need␈α∞not␈α∞be␈α∂generated␈α∞and
␈↓ ↓H␈↓then␈αpushed␈αonto␈αthe␈αstack;␈αwe␈αcan␈αcompile␈αthe␈αother␈αarguments␈αfirst␈αand␈αthen,␈αjust␈αbefore␈αwe␈αcall
␈↓ ↓H␈↓the␈α⊂function,␈α⊂load␈α∂the␈α⊂appropriate␈α⊂␈↓αAC␈↓␈α∂with␈α⊂that␈α⊂constant.␈α∂A␈α⊂similar␈α⊂argument␈α∂can␈α⊂be␈α⊂used␈α∂for
␈↓ ↓H␈↓postponing␈αthe␈αloading␈αof␈αvariable␈αreferences␈↓π 212␈↓.␈αThe␈αthird␈αtrivial␈αconstruct␈αfor␈αthis␈α␈↓αcomplis␈↓␈αis␈αthe
␈↓ ↓H␈↓handling␈α
of␈α
␈↓αcar-cdr␈↓␈α
chains.␈α
We␈α
will␈α
use␈α
our␈α
augmented␈α
instruction␈α
set␈α
to␈α
perform␈α
computation␈α
of
␈↓ ↓H␈↓␈↓αcar␈↓s␈α∪and␈α∩␈↓αcdr␈↓s␈α∪directly␈α∩to␈α∪a␈α∩specified␈α∪␈↓αAC␈↓.␈α∩ Complex␈α∪arguments␈α∩are␈α∪those␈α∩which␈α∪require␈α∩some
␈↓ ↓H␈↓non-trivial␈α
computation;␈α
each␈α∞non-trivial␈α
computation␈α
will␈α∞be␈α
prefaced␈α
with␈α∞a␈α
␈↓αPUSH␈↓␈α
to␈α∞save␈α
the
␈↓ ↓H␈↓current contents of ␈↓αAC1␈↓.
␈↓ ↓H␈↓Besides␈α∂the␈α∂compilation␈α∞of␈α∂efficient␈α∂code␈α∞we␈α∂would␈α∂also␈α∞like␈α∂to␈α∂make␈α∞the␈α∂compiler␈α∂efficient.␈α∞We
␈↓ ↓H␈↓would␈α⊂like␈α⊂to␈α⊂make␈α⊂the␈α⊂compiling␈α⊂process␈α⊃as␈α⊂one-pass␈α⊂as␈α⊂possible.␈α⊂Our␈α⊂basic␈α⊂tasks␈α⊂in␈α⊃the␈α⊂new
␈↓ ↓H␈↓␈↓αcomplis␈↓␈α
are␈α
classification␈α
of␈α
the␈αarguments␈α
and␈α
compilation␈α
of␈α
the␈α
code.␈αWith␈α
a␈α
little␈α
care␈α
we␈αcan␈α
do
␈↓ ↓H␈↓both␈αat␈αthe␈αsame␈αtime.␈αThere␈αis␈αnothing␈αproblematic␈αabout␈αthe␈αcompilation␈αof␈αthe␈α
trivial␈αcode␈↓π 213␈↓.
␈↓ ↓H␈↓We thus turn to the complex code.
␈↓ ↓H␈↓The␈αold␈α␈↓αcomplis␈↓␈αgenerated␈αa␈αblock␈α<code␈α␈↓αarg␈↓βi␈↓>-␈↓αPUSH␈↓␈αon␈αeach␈αcycle.␈αThat␈αcode␈αwas␈αfollowed␈αby␈αa
␈↓ ↓H␈↓␈↓αMOVE␈↓␈αto␈αmove␈αthe␈αlast␈αvalue␈αfrom␈α␈↓αAC1␈↓␈αto␈α␈↓αACn␈↓.␈αIn␈αthe␈αprevious␈αcompiler␈α␈↓αcompexp␈↓␈αwas␈αthe␈αmajor
␈↓ ↓H␈↓function;␈αit␈αhandled␈αthe␈αbulk␈αof␈αthe␈αcode␈αgeneration.␈αHere␈α␈↓αcomplis␈↓␈αwill␈αbe␈αthe␈αmajor␈αfunction.␈αThe
␈↓ ↓H␈↓old␈α␈↓αcomplis␈↓␈αhad␈αthree␈αstates:␈αempty␈αargument␈αlist,␈αsingleton␈αargument␈αlist,␈αand␈α
otherwise␈αcondition.
␈↓ ↓H␈↓The␈α⊂new␈α⊂␈↓αcomplis␈↓␈α∂has␈α⊂two␈α⊂states;␈α∂this␈α⊂is␈α⊂done␈α∂to␈α⊂make␈α⊂␈↓αcomplis␈↓␈α∂shorter.␈α⊂ On␈α⊂each␈α⊂cycle␈α∂through
␈↓ ↓H␈↓␈↓αcomplis␈↓␈αwe␈αgenerate␈αa␈α
␈↓αPUSH␈↓-<code ␈↓αarg␈↓βi␈↓>␈αsequence.␈αNow␈αwe␈αhave␈α
a␈αspurious␈α␈↓αPUSH␈↓␈αon␈α
the␈α␈↓↓front␈↓
␈↓ ↓H␈↓of the sequence; one ␈↓αrest␈↓ will take care of ␈↓↓that␈↓.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 212␈↓␈α∂But␈α∂note␈α∂that␈α∂the␈α∞argument␈α∂for␈α∂variables␈α∂is␈α∂shaky;␈α∞if␈α∂our␈α∂compiler␈α∂handled␈α∂programs␈α∞with
␈↓ ↓H␈↓side-effects␈αthen␈αwe␈α
could␈α␈↓↓not␈↓␈αbe␈α
sure␈αthat␈αthe␈α
postponed␈αvalue␈αwould␈α
be␈αthe␈αsame␈α
as␈αthat␈αgotten␈α
if
␈↓ ↓H␈↓we had loaded it at the "proper" time.
␈↓ ↓H␈↓␈↓π 213␈↓ That's why it's trivial!
␈↓ ↓H␈↓␈↓↓6.14␈↓ πfEfficiency: Calling Sequences 327␈↓
␈↓ ↓H␈↓We␈α
must␈αalso␈α
generate␈α
a␈αlist␈α
of␈α
␈↓αPOP␈↓s␈αto␈α
suffix␈αto␈α
the␈α
complex␈αcode␈α
to␈α
get␈αthe␈α
saved␈α
values␈αback
␈↓ ↓H␈↓into␈α⊂the␈α∂proper␈α⊂␈↓αAC␈↓'s:␈α∂one␈α⊂pop␈α⊂for␈α∂each␈α⊂argument.␈α∂ The␈α⊂␈↓↓last␈↓␈α⊂␈↓αPOP␈↓␈α∂should␈α⊂be␈α∂modified␈α⊂to␈α⊂be␈α∂a
␈↓ ↓H␈↓␈↓αMOVE␈↓␈αsince␈αwe␈αhave␈αnot␈αgenerated␈αthe␈αcorresponding␈α␈↓αPUSH␈↓.␈αThe␈αmemory␈αfield␈αof␈αthe␈αlast␈α␈↓αPOP␈↓
␈↓ ↓H␈↓has the needed information; it tells us where the ␈↓αMOVE␈↓ we want to make should go:
␈↓ ↓H␈↓α␈↓ ¬∞(POP P N) => (MOVE N 1)
␈↓ ↓H␈↓This␈αmodified␈α
list␈αof␈α␈↓αPOP␈↓s␈α
is␈αadded␈αto␈α
the␈αcode␈αsequence,␈α
followed␈αby␈αany␈α
trivial␈αcode␈α
which␈αwe
␈↓ ↓H␈↓may␈α⊂have␈α⊂generated.␈α⊃Note␈α⊂that␈α⊂this␈α⊃reordering␈α⊂is␈α⊂strictly␈α⊃an␈α⊂efficiency␈α⊂consideration␈α⊃under␈α⊂the
␈↓ ↓H␈↓assumption␈α
that␈αthe␈α
␈↓αAC␈↓'s␈αare␈α
being␈α
used␈αto␈α
simulate␈αa␈α
temporary␈α
␈↓αdest␈↓␈αblock,␈α
which␈αwill␈α
immediately
␈↓ ↓H␈↓become␈αa␈α
block␈αof␈α
local␈αbindings,␈α
and␈αwhich␈αare␈α
subject␈αto␈α
local␈αuse␈α
only.␈αWith␈α
this␈αintroduction,
␈↓ ↓H␈↓here is ␈↓αcomplis␈↓ and friends:
␈↓ ↓H␈↓␈↓αcomplis <= λ[[u;off;vpl] complis␈↓λ'␈↓α[u;off;off;vpl;();();();1]␈↓
␈↓ ↓H␈↓αcomplis␈↓λ'␈↓α <= λ[[u;org;off;vpl;triv;cmplx;pop;ac]
␈↓ ↓H␈↓α␈↓ αx[null[u] →␈↓ βx[null[cmplx] → triv;
␈↓ ↓H␈↓α␈↓ αx␈↓ βx ␈↓
t␈↓α → append␈↓ ¬_[rest[cmplx]
␈↓ ↓H␈↓α␈↓ αx␈↓ βx␈↓ ¬_ list[mkmove[mem[first[pop]];1]];
␈↓ ↓H␈↓α␈↓ αx␈↓ βx␈↓ ¬_ rest[pop];
␈↓ ↓H␈↓α␈↓ αx␈↓ βx␈↓ ¬_ triv]];
␈↓ ↓H␈↓α␈↓ αx isconst[first[u]] → complis␈↓λ'␈↓α[␈↓ ¬hrest[u];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬horg;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬hoff;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬hvpl;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬hconcat[mkconst[ac;first[u]];triv];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬hcmplx;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬hpop;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬hadd1[ac]];
␈↓ ↓H␈↓α␈↓ αx isvar[first[u]] → complis␈↓λ'␈↓α[␈↓ ¬Hrest[u];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Horg;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Hoff;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Hvpl;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Hconcat[mkvar[ac;loc[first[u];off;vpl]];triv];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Hcmplx;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Hpop;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Hadd1[ac]];
␈↓ ↓H␈↓α␈↓ αx iscarcdr[first[u]] → complis␈↓λ'␈↓α[␈↓ ¬xrest[u];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬xorg;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬xoff;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬xvpl;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬xappend[␈↓ εhreverse[compcarcdr[ac;first[u];off;vpl]];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬x␈↓ εhtriv];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬xcmplx;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬xpop;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬xadd1[ac]];
␈↓ ↓H␈↓␈↓↓328 Dynamic Structure␈↓ &6.14␈↓
␈↓ ↓H␈↓α␈↓ αx iscond[first[u] → complis␈↓λ'␈↓α[␈↓ ¬Xrest[u];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Xorg;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Xsub1[off];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Xvpl;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Xtriv;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Xappend[␈↓ εHcmplx;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬X␈↓ εHconcat[␈↓ π(mkpush[1];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬X␈↓ εH␈↓ π(comcond[␈↓ λ_args␈↓βc␈↓α[first[u]];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬X␈↓ εH␈↓ π(␈↓ λ_gensym[];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬X␈↓ εH␈↓ π(␈↓ λ_off;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬X␈↓ εH␈↓ π(␈↓ λ_vpl]]];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Xconcat[mkpop[ac];pop];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬Xadd1[ac]];
␈↓ ↓H␈↓α␈↓ αx ␈↓
t␈↓α → complis␈↓λ'␈↓α[␈↓ ∧(rest[u];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(org;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(sub1[off];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(vpl;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(triv;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(append[␈↓ ¬_cmplx;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬_concat[␈↓ ¬xmkpush[1];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬_␈↓ ¬xλ[[z] compapply[␈↓ πXfunc[first[u]];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬_␈↓ ¬x␈↓ πXcomplis[␈↓ λHz;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬_␈↓ ¬x␈↓ πX␈↓ λHoff;
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬_␈↓ ¬x␈↓ πX␈↓ λHvpl];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬_␈↓ ¬x␈↓ πXlength[z]]]
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(␈↓ ¬_␈↓ ¬x [arglist[first[u]] ]];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(concat[mkpop[ac];pop];
␈↓ ↓H␈↓α␈↓ αx␈↓ ∧(add1[ac]]]
␈↓ ↓H␈↓αmkmove <= λ[[ac;loc][eq[ac;loc] → (); ␈↓
t␈↓α → list[MOVE;ac;loc]]]
␈↓ ↓H␈↓αcompcarcdr <= λ[[ac;exp;off;vpl]
␈↓ ↓H␈↓α␈↓ α_␈↓ β([isvar[arg[exp]] → list[mkcarcdr[␈↓ εXfunc[exp];
␈↓ ↓H␈↓α␈↓ α_␈↓ β(␈↓ ∧8␈↓ εXac;
␈↓ ↓H␈↓α␈↓ α_␈↓ β(␈↓ ∧8␈↓ εXloc[arg[exp];off;vpl]]]
␈↓ ↓H␈↓α␈↓ α_␈↓ β(␈↓
t␈↓α → concat[␈↓ ∧8mkcarcdr_ac[func[exp];ac;ac];
␈↓ ↓H␈↓α␈↓ α_␈↓ β(␈↓ ∧8compcarcdr[ac;second[exp];off;vpl]]]]
␈↓ ↓H␈↓␈↓↓6.14␈↓ πfEfficiency: Calling Sequences 329␈↓
␈↓ ↓H␈↓αiscarcdr <=λ[[u]␈↓ β([iscar[u] →iscarcdr[arg[u]]
␈↓ ↓H␈↓α␈↓ α_␈↓ β( iscdr[u] →iscarcdr[arg[u]]
␈↓ ↓H␈↓α␈↓ α_␈↓ β( atom[u] → ␈↓
t␈↓α
␈↓ ↓H␈↓α␈↓ α_␈↓ β( ␈↓
t␈↓α → ␈↓
f␈↓α ]]
␈↓ ↓H␈↓αiscar <= λ[[x] eq[func[x];CAR]]
␈↓ ↓H␈↓αiscdr <= λ[[x] eq[func[x];CDR]]
␈↓ ↓H␈↓αmkcarcdr <=λ[[carcdr;ac;loc] concat[carcdr;concat[ac;loc]]]
␈↓ ↓H␈↓␈↓ ¬~␈↓↓6.15 Efficiency: Predicates␈↓
␈↓ ↓H␈↓We␈α⊃have␈α⊃already␈α∩noted␈α⊃in␈α⊃Section 6.13␈α∩that␈α⊃some␈α⊃efficiencies␈α⊃are␈α∩possible␈α⊃in␈α⊃the␈α∩handling␈α⊃of
␈↓ ↓H␈↓predicates␈α⊂inside␈α⊃of␈α⊂conditional␈α⊂expressions.␈α⊃Here␈α⊂we␈α⊂will␈α⊃examine␈α⊂more␈α⊂possibilities.␈α⊃The␈α⊂first
␈↓ ↓H␈↓point␈αof␈α
contention␈αis␈αthat␈α
the␈αcurrent␈α
␈↓αcompclause␈↓␈αis␈α␈↓↓not␈↓␈α
good␈αenough.␈α
We␈αwant␈αto␈α
be␈αable␈α
to␈αuse
␈↓ ↓H␈↓the␈α∀Boolean␈α∀special␈α∪forms:␈α∀␈↓αand[u␈↓β1␈↓α; ...;u␈↓βn␈↓α]␈↓␈α∀and␈α∀␈↓αor[u␈↓β1␈↓α; ...;u␈↓βn␈↓α]␈↓.␈α∪The␈α∀definition␈α∀of␈α∀these␈α∪constructs
␈↓ ↓H␈↓required␈α∞they␈α∞not␈α∞evaluate␈α∞any␈α∞more␈α∞arguments␈α
than␈α∞necessary.␈α∞ We␈α∞can␈α∞use␈α∞this␈α∞property␈α
when
␈↓ ↓H␈↓using␈α␈↓αand␈↓␈αand␈α␈↓αor␈↓␈αas␈αpredicates␈αin␈αconditional␈αexpressions.␈α We␈αwill␈αadd␈αrecognizers␈αfor␈α␈↓αand␈↓␈αand␈α␈↓αor␈↓
␈↓ ↓H␈↓inside ␈↓αcompclause␈↓ and will add a new section to the compiler to deal with their compilation.
␈↓ ↓H␈↓First, here is the structure of typical code sequences:
␈↓ ↓H␈↓α␈↓ αXand[u␈↓β1␈↓α; ... u␈↓βn␈↓α] → e;␈↓ ε8or[u␈↓β1␈↓α; ... u␈↓βn␈↓α] → e;
␈↓ ↓H␈↓α␈↓ αX ␈↓gives:␈↓ ε8gives:␈↓α
␈↓ ↓H␈↓α␈↓ αX <code for u␈↓β1␈↓α>␈↓ ε8 <code for u␈↓β1␈↓α>
␈↓ ↓H␈↓α␈↓ αX (JUMPF 1 lint)␈↓ ε8 (JUMPT 1 loc)
␈↓ ↓H␈↓α␈↓ αX <code for u␈↓β2␈↓α>␈↓ ε8 <code for u␈↓β2␈↓α>
␈↓ ↓H␈↓α␈↓ αX (JUMPF 1 lint)␈↓ ε8 (JUMPT 1 loc)
␈↓ ↓H␈↓α␈↓ αX . . .␈↓ ε8 . . .
␈↓ ↓H␈↓α␈↓ αX <code for u␈↓βn␈↓α>␈↓ ε8 <code for u␈↓βn␈↓α>
␈↓ ↓H␈↓α␈↓ αX (JUMPF 1 lint)␈↓ ε8 (JUMPT 1 loc)
␈↓ ↓H␈↓α␈↓ αX (JUMP loc)␈↓ ε8 (JUMP lint)
␈↓ ↓H␈↓α␈↓ αXloc␈↓ ε8loc
␈↓ ↓H␈↓α␈↓ αX ␈↓<code for ␈↓αe␈↓>␈↓ ε8 <code for ␈↓αe␈↓>␈↓α
␈↓ ↓H␈↓α␈↓ αX (JUMP lout)␈↓ ε8 (JUMP lout)
␈↓ ↓H␈↓α␈↓ αXlint␈↓ ε8lint
␈↓ ↓H␈↓The␈α
label␈α␈↓αlint␈↓␈α
indicates␈α
the␈αnext␈α
clause␈α
in␈αthe␈α
conditional␈α
expression.␈αNote␈α
the␈α
symmetry␈αbetween
␈↓ ↓H␈↓the␈α⊂code␈α⊃for␈α⊂␈↓αand␈↓␈α⊂and␈α⊃the␈α⊂code␈α⊂for␈α⊃␈↓αor␈↓.␈α⊂There␈α⊂is␈α⊃a␈α⊂slight␈α⊂inefficiency␈α⊃in␈α⊂␈↓αand␈↓␈α⊃with␈α⊂␈↓α(JUMP loc)␈↓
␈↓ ↓H␈↓immedately followed by ␈↓αloc␈↓, but we can easily remove that.
␈↓ ↓H␈↓␈↓↓330 Dynamic Structure␈↓ (6.15␈↓
␈↓ ↓H␈↓Here is a ␈↓αcompclause␈↓ which will generate it:
␈↓ ↓H␈↓αcompclause <=λ[[p;loc;glob;off;vpl] append[␈↓ ¬xcompred[ante[p];loc;off;vpl];
␈↓ ↓H␈↓α␈↓ ¬xcompexp[conseq[p];off;vpl];
␈↓ ↓H␈↓α␈↓ ¬xlist[mkjump[glob];loc]]]
␈↓ ↓H␈↓αcompred <= λ[[p;lint;off;vpl]␈↓ ∧H[isand[p] → compandor[␈↓ εxargs[p];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ εxoff;
␈↓ ↓H␈↓α␈↓ ∧H␈↓ εxvpl;
␈↓ ↓H␈↓α␈↓ ∧H␈↓ εxlist[mkjumpnil[lint]];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ εx()];
␈↓ ↓H␈↓α␈↓ ∧H isor[p] → λ[[loc] compandor[␈↓ π8args[p];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ εx␈↓ π8off;
␈↓ ↓H␈↓α␈↓ ∧H␈↓ εx␈↓ π8vpl;
␈↓ ↓H␈↓α␈↓ ∧H␈↓ εx␈↓ π8list[mkjumpt[loc]];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ εx␈↓ π8list[mkjmp[lint];loc]]][gensym[]];
␈↓ ↓H␈↓α␈↓ ∧H ␈↓
t␈↓α → append[compexp[p;off;vpl];list[mkjumpf[lint]]] ]]
␈↓ ↓H␈↓αcompandor <=λ[[u;off;vpl;inst;fini]␈↓ ¬_[null[u] → fini;
␈↓ ↓H␈↓α␈↓ ¬_ ␈↓
t␈↓α → append[␈↓ εHcompexp[first[u];off;vpl];
␈↓ ↓H␈↓α␈↓ ¬_␈↓ εHinst;
␈↓ ↓H␈↓α␈↓ ¬_␈↓ εHcompandor[rest[u];off;vpl;inst;fini]] ]]]
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓␈↓↓I␈↓␈αWe␈α
should␈αrecognize␈α
the␈αconstruct␈α
␈↓
t␈↓ →␈↓αe␈↓βi␈↓␈αin␈α
conditional␈αexpressions␈α
and␈αcompile␈α
special␈αcode␈αfor␈α
it.
␈↓ ↓H␈↓We should also realize that in the construct:
␈↓ ↓H␈↓α␈↓ ¬"[p␈↓β1␈↓α → e␈↓β1␈↓α ... ␈↓
t␈↓α → e␈↓βi␈↓α; ...p␈↓βn␈↓α → e␈↓βn␈↓α]
␈↓ ↓H␈↓we␈αcan␈α␈↓↓never␈↓␈αreach␈αany␈αpart␈αof␈αthe␈αconditional␈αafter␈αthe␈α␈↓
t␈↓-predicate.␈α Therefore␈αno␈αcode␈αshould␈αbe
␈↓ ↓H␈↓generated. Rewrite the compiler to handle these additional observations about conditionals.
␈↓ ↓H␈↓The␈αsecond␈αpoint,␈αabove,␈αis␈αa␈αspecial␈αinstance␈αof␈αa␈αgeneral␈αcompiling␈αquestion.␈α How␈αclever␈αshould
␈↓ ↓H␈↓the␈αcompiler␈α
be?␈αIf␈αit␈α
can␈αrecognize␈αthat␈α
a␈αpiece␈α
of␈αprogram␈αcan␈α
never␈αbe␈αreached,␈α
should␈αit␈αtell␈α
the
␈↓ ↓H␈↓user or should it compile minimal code?
␈↓ ↓H␈↓␈↓↓II␈↓ Write a new ␈↓αcompile␈↓ including all the efficiency considerations discussed so far.
␈↓ ↓H␈↓␈↓↓III␈↓␈αWhen␈αwe␈αapply␈αthe␈αconvention␈αthat␈αanything␈αnon-␈↓αNIL␈↓␈αis␈αa␈αrepresentation␈αof␈αtruth,␈αit␈α
is␈αoften
␈↓ ↓H␈↓␈↓↓6.15␈↓ λQEfficiency: Predicates 331␈↓
␈↓ ↓H␈↓convenient␈α∂to␈α∂evaluate␈α∂␈↓αand␈↓␈α∂and␈α∂␈↓αor␈↓␈α∂for␈α∂"value".␈α∂ That␈α∂is␈α∂their␈α∂value␈α∂is␈α∂either␈α∂␈↓αNIL␈↓␈α∂or␈α∂non-␈↓αNIL␈↓.
␈↓ ↓H␈↓Extend our compiler to handle such uses of these functions.
␈↓ ↓H␈↓␈↓↓IV␈↓ Extend the compiler to compile efficient code for compositions of the predicates ␈↓αand␈↓, ␈↓αor␈↓, and ␈↓αnot␈↓.
␈↓ ↓H␈↓␈↓ ¬≡␈↓↓6.16 A Compiler for ␈↓αprogs␈↓↓␈↓α
␈↓ ↓H␈↓The␈αcompiler␈α
of␈αthis␈αsection␈α
will␈αnot␈αcompile␈α
all␈α␈↓αprog␈↓s;␈αit␈α
is␈αonly␈αintended␈α
to␈αdemonstrate␈α
some␈αof
␈↓ ↓H␈↓the salient features of a ␈↓αprog␈↓ compiler. They are:
␈↓ ↓H␈↓␈↓↓1.␈↓␈αHandling␈αof␈αassignments.␈αSince␈αwe␈αare␈αassuming␈αlocal␈αvariables,␈αthen␈αstorage␈αto␈αthe␈αvalue
␈↓ ↓H␈↓␈↓ α_stack is sufficient.
␈↓ ↓H␈↓␈↓↓2.␈↓ The ␈↓αgo␈↓-label pair. We will assume that this can be passed off to the assembler.
␈↓ ↓H␈↓␈↓↓3.␈↓␈αOn␈αleaving␈α
a␈α␈↓αprog␈↓-body␈αwe␈αhave␈α
to␈αremove␈αthe␈α␈↓αprog␈↓-variables␈α
from␈αthe␈αtop␈αof␈α
the␈αstack.
␈↓ ↓H␈↓␈↓ α_This is done by comparing the current ␈↓αoff␈↓ with ␈↓αvpl␈↓.
␈↓ ↓H␈↓αcompprog <=λ[[locals;body;off;vpl]
␈↓ ↓H␈↓α␈↓ β(λ[[n]append[␈↓ ∧Xmkpushlistnil[n];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧Xcompbody[␈↓ ¬Xbody;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ¬Xlabels[body];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ¬Xdifference[off;n];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ¬Xpruploc[locals;-off;vpl];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ¬Xn;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ¬Xgensym[]]]
␈↓ ↓H␈↓α␈↓ β( [length[locals]]
␈↓ ↓H␈↓αpruploc <= λ[[locals;off;vpl]␈↓ ∧8[null[locals] → vpl;
␈↓ ↓H␈↓α␈↓ ∧8 ␈↓
t␈↓α → pruploc[␈↓ ¬hrest[locals];
␈↓ ↓H␈↓α␈↓ ∧8␈↓ ¬hadd1[off];
␈↓ ↓H␈↓α␈↓ ∧8␈↓ ¬hconcat[cons[first[locals];off];vpl]]]]
␈↓ ↓H␈↓αlabels <= λ[[body]␈↓ βX[null[body] → ();
␈↓ ↓H␈↓α␈↓ βX islabel[first[body]] → concat[first[body];labels[rest[body]]];
␈↓ ↓H␈↓α␈↓ βX ␈↓
t␈↓α → labels[rest[body]]]]
␈↓ ↓H␈↓␈↓↓332 Dynamic Structure␈↓ )6.16␈↓
␈↓ ↓H␈↓αcompbody <= λ[[body;labels;off;vpl;n;exit]
␈↓ ↓H␈↓α␈↓ β([null[body] →list[mkconst[1;NIL];exit;mksync[n]];
␈↓ ↓H␈↓α␈↓ β( islabel[first[body]] → concat[first[body];compbody[␈↓ λ(rest[body];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8␈↓ πh␈↓ λ(labels;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8␈↓ πh␈↓ λ(off;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8␈↓ πh␈↓ λ(vpl;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8␈↓ πh␈↓ λ(n;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8␈↓ πh␈↓ λ(exit]];
␈↓ ↓H␈↓α␈↓ β( isgo[first[body]] → append[␈↓ ε(list[compgo[arg[first[body]];labels]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(compbody[␈↓ π8rest[body];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8labels;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8off;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8vpl;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8n;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8exit]];
␈↓ ↓H␈↓α␈↓ β( isret[first[body]] → append[␈↓ ε(compexp[arglist[first[body]];off;vpl];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(sync[off;vpl];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(list[mkjump[exit]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(compbody[␈↓ π8rest[body];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8labels;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8off;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8vpl;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8n;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8exit]];
␈↓ ↓H␈↓α␈↓ β( issetq[first[body]] → append[␈↓ ε(compexp[rhs[first[body]];off;vpl];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(list[mkmovem[␈↓ πh1;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8␈↓ πhloc[lhs[first[body]];off;vpl]]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(compbody[␈↓ π8rest[body];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8labels;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8off;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8vpl;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8n;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8exit]];
␈↓ ↓H␈↓α␈↓ β( iscond[first[body]] → append[␈↓ ε(compcondprog[arg[first[body]]];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(compbody[␈↓ π8rest[body];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8labels;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8off;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8vpl;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8n;
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧X␈↓ ε(␈↓ π8exit]];
␈↓ ↓H␈↓α␈↓ β(␈↓
t␈↓α → append[␈↓ ∧Xcompexp[first[body];off;vpl];
␈↓ ↓H␈↓α␈↓ β(␈↓ ∧Xcompbody[rest[body];off;vpl;n;exit]]]]
␈↓ ↓H␈↓αcompgo <= λ[[x;l][member[x;l] → mkjump[x]; ␈↓
t␈↓α → err[UNDEFINED_TAG]]];
␈↓ ↓H␈↓␈↓↓6.16␈↓ λYA Compiler for ␈↓αprogs␈↓↓ 333␈↓α
␈↓ ↓H␈↓This␈α
␈↓αcompprog␈↓␈α∞only␈α
handles␈α
a␈α∞subset␈α
of␈α∞the␈α
semantics␈α
of␈α∞␈↓αprog␈↓.␈α
We␈α
do␈α∞not␈α
handle␈α∞any␈α
non-local
␈↓ ↓H␈↓jumps;␈α
a␈αnew␈α
list␈α
of␈αlabels␈α
is␈α
made␈αup␈α
on␈αentry␈α
to␈α
a␈α␈↓αprog␈↓␈α
and␈α
only␈αthat␈α
set␈α
of␈αlabels␈α
is␈αaccessible␈α
for
␈↓ ↓H␈↓␈↓αgo␈↓s.␈α∞ As␈α∂a␈α∞further␈α∞restriction,␈α∂we␈α∞also␈α∞assume␈α∂that␈α∞the␈α∞␈↓αprog␈↓␈α∂variables␈α∞are␈α∞used␈α∂in␈α∞a␈α∂strictly␈α∞local
␈↓ ↓H␈↓fashion.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓Write ␈↓αcompcondprog␈↓.
␈↓ ↓H␈↓␈↓ ¬↔␈↓↓6.17 Further Optimizations␈↓
␈↓ ↓H␈↓This␈α∩section␈α∩is␈α∩in␈α∩the␈α∩nature␈α∩of␈α⊃hints␈α∩and␈α∩possibilities␈α∩for␈α∩expansion␈α∩of␈α∩the␈α∩basic␈α⊃compiling
␈↓ ↓H␈↓algorithms.
␈↓ ↓H␈↓One␈α
of␈αthe␈α
first␈α
things␈αto␈α
note␈α
about␈αthe␈α
compiling␈α
algorithm␈αis␈α
its␈α
lack␈αof␈α
knowledge␈α
about␈αwhat␈α
it
␈↓ ↓H␈↓has␈α∂in␈α∂the␈α∂various␈α∂␈↓αAC␈↓'s.␈α∂Frequently␈α∂the␈α∂compiled␈α∂code␈α∂will␈α∂load␈α∂up␈α∂one␈α∂of␈α∂the␈α∂registers␈α∂with␈α∂a
␈↓ ↓H␈↓quantity␈αthat␈αis␈αalready␈αthere.␈α
Thus␈αthe␈αfirst␈αsuggestion:␈αbuild␈α
a␈αlist␈αof␈αwhat's␈αin␈α
various␈αregisters.
␈↓ ↓H␈↓We␈α⊂know␈α⊂what's␈α⊂there␈α⊂when␈α⊂we␈α⊂enter␈α⊂the␈α⊂function;␈α⊂whenever␈α⊂we␈α⊂perform␈α⊂an␈α⊂operation␈α⊂which
␈↓ ↓H␈↓destroys␈α
a␈αregister␈α
then␈αwe␈α
have␈αto␈α
update␈αthe␈α
compiler's␈αmemory.␈α
Whenever␈αwe␈α
need␈α
a␈αquantity,
␈↓ ↓H␈↓we␈αcheck␈αthe␈αmemory.␈αIf␈αthe␈αobject␈αis␈αalready␈αin␈α
the␈α␈↓αAC␈↓'s␈αthen␈αwe␈αuse␈αit.␈αClearly␈αthere␈αis␈αa␈αpoint␈α
at
␈↓ ↓H␈↓which␈α
the␈α
complexity␈α
of␈α
the␈α
object␈α∞stored␈α
is␈α
too␈α
complicated␈α
to␈α
be␈α
worth␈α∞remembering.␈α
However,
␈↓ ↓H␈↓the␈αidea␈αcan␈αbe␈αused␈αquite␈αprofitably␈αfor␈αvariable␈αreferences␈αand␈αsimple␈αcomputations.␈αThis␈αidea␈αis
␈↓ ↓H␈↓a␈α∞simple␈α∞form␈α
of␈α∞␈↓↓common␈α∞sub␈α
expression␈α∞elimination␈↓.␈α∞For␈α
example,␈α∞assuming␈α∞the␈α∞the␈α
compiler
␈↓ ↓H␈↓knows that ␈↓αx␈↓ is in ␈↓αAC1␈↓, here's code for:
␈↓ ↓H␈↓α␈↓ ¬Rf[car[x];cdr[car[x]]].
␈↓ ↓H␈↓α␈↓ ¬H(CAR 1 1)
␈↓ ↓H␈↓α␈↓ ¬H(CDR 2 1)
␈↓ ↓H␈↓α␈↓ ¬H(CALL F)
␈↓ ↓H␈↓This␈αidea␈αcan␈αbe␈αextended.␈αThere␈αis␈αnothing␈αsacred␈αabout␈αknowing␈αonly␈αthe␈αcontents␈αof␈αthe␈α
special
␈↓ ↓H␈↓registers.␈α∂We␈α∂could␈α∂keep␈α∂a␈α∂history␈α∂of␈α∂the␈α∂partial␈α∂computations␈α∂in␈α∂the␈α∂stack.␈α∂Then␈α∂if␈α∂we␈α∂need␈α∞a
␈↓ ↓H␈↓partial␈αresult␈αwe␈αmight␈αfind␈αit␈αalready␈αcomputed␈αin␈αthe␈α␈↓αAC␈↓s␈αor␈αstored␈αon␈αthe␈αstack.␈αWe␈αmight␈αalso
␈↓ ↓H␈↓keep␈αtrack␈α
of␈αwhether␈αstack␈α
or␈α␈↓αAC␈↓␈αcontents␈α
are␈αstill␈α
needed.␈α For␈αexample,␈α
in␈αour␈αcompiled␈α
function
␈↓ ↓H␈↓␈↓αj␈↓␈αon␈αpage 316␈αwe␈αmight␈αhave␈αnoticed␈αthat␈αafter␈αthe␈αcall␈αon␈α␈↓αg␈↓,␈αthe␈αvalue␈αof␈α␈↓αx␈↓␈αwas␈αno␈αlonger␈αneeded;
␈↓ ↓H␈↓therefore␈αwe␈αneed␈α
not␈αsave␈α␈↓αx␈↓.␈αSimilarly␈α
we␈αdon't␈αneed␈α
the␈αvalue␈αof␈α␈↓αy␈↓␈α
after␈αthe␈αcall␈α
on␈α␈↓αh␈↓.␈αIf␈αwe␈α
build
␈↓ ↓H␈↓this␈α
kind␈α
of␈α
information␈α
into␈α
a␈α
compiler,␈α
we␈α
can␈α
generate␈α
more␈α
efficient␈α
code.␈α
However,␈α∞many␈α
of
␈↓ ↓H␈↓these ideas must be used with some care. Side-effects can destroy the validity of partial results.
␈↓ ↓H␈↓␈↓↓334 Dynamic Structure␈↓ )6.17␈↓
␈↓ ↓H␈↓Notice␈αthat␈αwe␈αare␈αcomparing␈αthe␈α␈↓↓symbolic␈↓␈αvalues␈α
in␈αthe␈α␈↓αAC␈↓'s␈αor␈αstack;␈αwe␈αcannot␈αlook␈α
for␈αactual
␈↓ ↓H␈↓values.␈α∞This␈α∞idea␈α∞of␈α∞symbolic␈α∞processing␈α∞can␈α∞be␈α∞exploited␈α∞at␈α∞a␈α∞much␈α∞more␈α∞sophisticated␈α∞level␈α∞in
␈↓ ↓H␈↓LISP␈α∀compilers.␈α∀ In␈α∃particular,␈α∀we␈α∀can␈α∀perform␈α∃program␈α∀transformations.␈α∀ For␈α∃example,␈α∀the
␈↓ ↓H␈↓compiler␈α∪can␈α∪rewrite␈α∩program␈α∪segments␈α∪taking␈α∪advantage␈α∩of␈α∪transformations␈α∪it␈α∪knows.␈α∩These
␈↓ ↓H␈↓transformations␈α∩typically␈α∩involve␈α∩equivalence␈α∩preserving␈α⊃operations␈α∩which␈α∩might␈α∩lead␈α∩to␈α⊃more
␈↓ ↓H␈↓efficient compiled code.
␈↓ ↓H␈↓For␈α⊃example␈α∩several␈α⊃LISP␈α⊃compilers␈α∩have␈α⊃the␈α⊃ability␈α∩to␈α⊃perform␈α⊃recursion␈α∩removal,␈α⊃replacing
␈↓ ↓H␈↓recursive programs with equivalent iterative versions␈↓π 214␈↓. Here's a case:
␈↓ ↓H␈↓α␈↓ βPrev <= λ[[x;y][null[x] → y; ␈↓
t␈↓α → rev[rest[x];concat[first[x];y]]]]
␈↓ ↓H␈↓This program is automatically rewritten as:
␈↓ ↓H␈↓αrev <= λ[[x;y] prog[[]␈↓ βxl␈↓ ∧([null[x] → return[y]];
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧(y ← concat[first[x];y];
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧(x ← rest[x];
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧(go[l] ]]
␈↓ ↓H␈↓This␈αsecond␈α
version␈αmakes␈α
no␈αdemands␈α
on␈αthe␈α
run-time␈αstack␈α
to␈αsave␈α
its␈αpartial␈α
computation␈αlike
␈↓ ↓H␈↓the recursive version would. Typically this second version will execute faster.
␈↓ ↓H␈↓A␈αmajor␈α
obstacle␈αto␈α
most␈αkinds␈αof␈α
optimization␈αis␈α
the␈αunrestricted␈αuse␈α
of␈αlabels␈α
and␈α␈↓αgo␈↓s.␈αConsider␈α
a
␈↓ ↓H␈↓piece␈αof␈αcompiler␈αcode␈αwhich␈αhas␈αa␈αlabel␈αattached␈αto␈αit.␈α Before␈αwe␈αcan␈αbe␈αassured␈αof␈αthe␈αintegrity
␈↓ ↓H␈↓of␈α
an␈α
␈↓αAC␈↓␈α
we␈α
must␈α
ascertain␈α
that␈α
every␈α
possible␈α
path␈α
to␈α
that␈α
label␈α
maintains␈α
that␈α
␈↓αAC␈↓.␈α
This␈α
is␈αa␈α
very
␈↓ ↓H␈↓difficult␈α∂task.␈α∂The␈α⊂label␈α∂and␈α∂goto␈α∂structure␈α⊂required␈α∂by␈α∂␈↓αcompile␈↓␈α∂is␈α⊂quite␈α∂simple.␈α∂However␈α⊂if␈α∂we
␈↓ ↓H␈↓wished␈α⊃to␈α⊃build␈α⊂an␈α⊃optimizing␈α⊃compiler␈α⊂for␈α⊃LISP␈α⊃with␈α⊂␈↓αprog␈↓s␈α⊃we␈α⊃would␈α⊂have␈α⊃to␈α⊃confront␈α⊂this
␈↓ ↓H␈↓problem.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓␈α
Extend␈αthe␈α
compiling␈αalgorithm␈α
to␈αremember␈α
what␈αit␈α
has␈αin␈α
its␈α␈↓αAC␈↓␈α
registers.␈αHow␈α
much␈α
of␈αthe
␈↓ ↓H␈↓scheme is dependent on lack of side-effects?
␈↓ ↓H␈↓␈↓↓2.␈↓␈αTitled:␈α"␈αIf␈αwe␈αonly␈αhad␈αan␈αinstruction...␈α"␈αWe␈αadvocate␈αan␈αinstruction,␈α␈↓αEXCH␈αac␈αloc␈↓,␈αwhich␈αwill
␈↓ ↓H␈↓exchange␈αthe␈αcontents␈αof␈αthe␈α␈↓αac␈↓␈αand␈αthe␈α␈↓αloc␈↓.␈αThis␈αinstruction␈αcould␈αbe␈αused␈αeffectively␈αon␈αthe␈αcode
␈↓ ↓H␈↓for ␈↓αj␈↓ on page 315 to save a ␈↓αPUSH-POP␈↓ pair.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 214␈↓ All these transformations are typically invisible to the user.
␈↓ ↓H␈↓␈↓↓6.17␈↓ λKFurther Optimizations 335␈↓
␈↓ ↓H␈↓Here's ␈↓αEXCH␈↓ in action, using the results of the previous exercise:
␈↓ ↓H␈↓α␈↓ αX((LAP J SUBR)␈↓ πλ␈↓; says ␈↓αj␈↓ is a function␈↓α
␈↓ ↓H␈↓α␈↓ αX (PUSH P 2)
␈↓ ↓H␈↓α␈↓ αX (CALL G)␈↓ πλ␈↓; call the function named ␈↓αg
␈↓ ↓H␈↓α␈↓ αX (EXCH 1 0 P)␈↓ πλ␈↓; save the value and dredge up ␈↓αy
␈↓ ↓H␈↓α␈↓ αX (CALL H)␈↓ πλ␈↓; call ␈↓αh
␈↓ ↓H␈↓α␈↓ αX (MOVE 2 1)
␈↓ ↓H␈↓α␈↓ αX (POP P 1)␈↓ πλ␈↓; preparation for␈↓α
␈↓ ↓H␈↓α␈↓ αX (CALL F)␈↓ πλ␈↓; calling ␈↓αf
␈↓ ↓H␈↓α␈↓ αX (RET))␈↓ πλ␈↓; exit.␈↓α AC1␈↓ still has the value from ␈↓αf.
␈↓ ↓H␈↓Look␈α
for␈α
general␈αsituations␈α
where␈α
␈↓αEXCH␈↓␈αcan␈α
be␈α
used.␈αIn␈α
your␈α
tour␈αthrough␈α
the␈α
compilers,␈α
try␈αto
␈↓ ↓H␈↓imagine other useful instructions.
␈↓ ↓H␈↓␈↓↓3.␈↓ Write code for the factorial function, and simulate the execution on ␈↓α2!␈↓.
␈↓ ↓H␈↓␈↓↓4.␈↓␈αWrite␈α
a␈αLISP␈α
function␈αto␈α
take␈αrecursive␈α
schemes␈αinto␈α
equivalent␈αiterative␈α
ones␈αin␈α
the␈αstyle␈αof␈α
the
␈↓ ↓H␈↓␈↓αrev␈↓␈α
example␈α
on␈α
page 334.␈α
Your␈α
first␈α
version␈α
need␈α
not␈α
be␈α
as␈α
efficient␈α
as␈α
the␈α
one␈α
advertized␈α
there,
␈↓ ↓H␈↓but try to make it better as you proceed. See [Dar 73] for this and related transformations.
␈↓ ↓H␈↓␈↓ ¬⊗␈↓↓6.18 Functional Arguments␈↓
␈↓ ↓H␈↓Function␈α∪variables␈α∩add␈α∪more␈α∩complication␈α∪to␈α∩the␈α∪compiling␈α∩algorithms.␈α∪ We␈α∩will␈α∪address␈α∩the
␈↓ ↓H␈↓simpler␈α∞cases␈α∞of␈α∂functional␈α∞arguments.␈α∞ There␈α∂are␈α∞two␈α∞issuses␈α∞involved:␈α∂what␈α∞to␈α∞compile␈α∂when␈α∞a
␈↓ ↓H␈↓␈↓αfunction␈↓␈αconstruct␈αis␈αrecognized;␈αand␈αwhat␈αto␈αdo␈αwhen␈αthe␈αfunction␈αposition␈αof␈αan␈αapplication␈α
is␈αa
␈↓ ↓H␈↓variable.
␈↓ ↓H␈↓Consider an example:
␈↓ ↓H␈↓α␈↓ ¬Kfoo[ ...;function[␈↓εf␈↓α];...]␈↓
␈↓ ↓H␈↓We␈α
generate␈α␈↓α(MOVEI␈α
1␈α␈↓εf␈↓α)␈↓␈α
and␈αcompile␈α
␈↓εf␈↓␈α
if␈αit␈α
is␈αa␈α
λ-definition;␈αotherwise␈α
we␈α
essentially␈αgenerate
␈↓ ↓H␈↓␈↓α(MOVEI 1 (QUOTE ␈↓εf␈↓α))␈↓.
␈↓ ↓H␈↓Assume ␈↓αfoo␈↓ is defined as:
␈↓ ↓H␈↓α␈↓ ¬
foo <= λ[[ ...;g; ...] ....g[t␈↓β1␈↓α; ...;t␈↓βn␈↓α]]
␈↓ ↓H␈↓␈↓↓336 Dynamic Structure␈↓ (6.18␈↓
␈↓ ↓H␈↓The␈α
instance␈α
of␈α
␈↓αg␈↓␈α
in␈α
␈↓αg[t␈↓β1␈↓α;␈α...;t␈↓βn␈↓α]]␈↓␈α
is␈α
a␈α
special␈α
case␈α
of␈αa␈α
computed␈α
function␈α
(page 144);␈α
in␈α
this␈αcase,␈α
the
␈↓ ↓H␈↓computation␈α⊂is␈α⊂only␈α∂a␈α⊂variable␈α⊂lookup.␈α⊂We␈α∂will␈α⊂display␈α⊂the␈α⊂more␈α∂general␈α⊂code␈α⊂for␈α⊂a␈α∂computed
␈↓ ↓H␈↓function call of the form:
␈↓ ↓H␈↓α␈↓ ¬␈exp[t␈↓β1␈↓α; ...;t␈↓βn␈↓α].
␈↓ ↓H␈↓We get:
␈↓ ↓H␈↓α␈↓ ∧Happend[␈↓ ¬8<compexp[exp;off;vpl];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬8list[mkalloc[1]];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬8<complis[(t␈↓β1␈↓α; ...;t␈↓βn␈↓α);off-1;vpl]>
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬8list[mkalloc[1]];
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬8((CALLF n 0 P))
␈↓ ↓H␈↓α␈↓ ∧H␈↓ ¬8((SUB P (C 1))]
␈↓ ↓H␈↓The␈α∂calling␈α∂structure␈α∂for␈α∂a␈α∂functional␈α⊂argument␈α∂is␈α∂slightly␈α∂different.␈α∂The␈α∂arguments␈α∂are␈α⊂on␈α∂the
␈↓ ↓H␈↓stack␈α∞but,␈α
more␈α∞importantly,␈α∞note␈α
that␈α∞the␈α
call␈α∞must␈α∞always␈α
be␈α∞trapped␈α
and␈α∞decoded.␈α∞ We␈α
cannot
␈↓ ↓H␈↓replace␈α⊂that␈α⊂call␈α⊂with␈α⊂a␈α⊂␈↓αPUSHJ␈↓␈α⊂to␈α⊂some␈α⊂machine␈α⊂language␈α⊂code␈α⊂for␈α⊂the␈α⊂function␈α⊂because␈α⊂the
␈↓ ↓H␈↓function␈αreferred␈αto␈α
can␈αchange.␈α We␈αuse␈α
a␈α␈↓αCALLF␈↓␈αinstruction␈αto␈α
designate␈αa␈αcall␈αon␈α
a␈αfunctional
␈↓ ↓H␈↓argument.␈α If␈αthe␈αfuntion␈αis␈αa␈αvariable␈αname␈αwe␈αcannot␈αknow␈αat␈αcompile-time,␈αwhat␈αto␈α␈↓αPUSHJ␈↓␈αto.
␈↓ ↓H␈↓Since␈αthe␈αvalue␈αof␈αthe␈αexpression␈αmay␈αvery␈αwell␈αchange␈αduring␈αexecution␈αwe␈αcan␈α␈↓↓never␈↓␈αreplace␈αthe
␈↓ ↓H␈↓␈↓αCALL␈↓ with a ␈↓αPUSHJ␈↓.
␈↓ ↓H␈↓Often,␈α⊃unneeded␈α⊃generality␈α⊃allowed␈α⊃by␈α⊂functional␈α⊃arguments␈α⊃can␈α⊃be␈α⊃compiled␈α⊃out.␈α⊂ Production
␈↓ ↓H␈↓LISP␈α
compilers,␈α
like␈α
the␈α
MacLISP␈α
compiler,␈α
are␈α
able␈α
to␈α
compile␈α
efficient␈α
code␈α
for␈α
many␈αinstances␈α
of
␈↓ ↓H␈↓the␈α⊃LISP␈α⊃mapping␈α⊃functions,␈α⊃like␈α⊃␈↓αmaplist␈↓;␈α⊃in␈α⊃the␈α⊃general␈α⊃case␈α⊃the␈α⊃code␈α⊃must␈α∩expect␈α⊃arbitrary
␈↓ ↓H␈↓functional arguments.
␈↓ ↓H␈↓The␈α∞problems␈α∂of␈α∞compiling␈α∞efficient␈α∂code␈α∞become␈α∞magnified␈α∂if␈α∞generalized␈α∞control␈α∂structures␈α∞are
␈↓ ↓H␈↓anticipated.␈αThe␈αproblem␈αis␈α
similar␈αto␈αthat␈αof␈αrecognizing␈α
an␈αimplied␈αloop␈αconstruct␈αin␈α
a␈αprogram
␈↓ ↓H␈↓using␈α∞labels␈α∞and␈α∞␈↓αgo␈↓'s␈α∞to␈α∞control␈α∞the␈α∞algorithm.␈α∞Control␈α∞constructs␈α∞like␈α∞␈↓αcatch␈↓␈α∞and␈α∞␈↓αthrow␈↓␈α∞(page 184)
␈↓ ↓H␈↓have␈α∞some␈α
advantages␈α∞here;␈α
rather␈α∞than␈α
using␈α∞evaluation␈α
relative␈α∞to␈α
arbitrary␈α∞access␈α∞and␈α
control
␈↓ ↓H␈↓environments␈α
([Bob 73a]),␈α
these␈α
constructs␈α
do␈α
impose␈α
some␈α
regularity␈α
which␈α
the␈α
compiler␈α
and␈αthe
␈↓ ↓H␈↓programmer can exploit.
␈↓ ↓H␈↓␈↓ ∧⎇␈↓↓6.19 Macros and Special Forms␈↓
␈↓ ↓H␈↓We␈α⊃now␈α∩wish␈α⊃to␈α∩extend␈α⊃our␈α∩compiler␈α⊃to␈α⊃handle␈α∩macro␈α⊃definitions.␈α∩ Consider␈α⊃the␈α∩example␈α⊃of
␈↓ ↓H␈↓defining␈α⊂␈↓αplus␈↓␈α⊂of␈α⊂an␈α⊂indefinite␈α⊂number␈α⊂of␈α⊂arguments␈α⊂given␈α⊂on␈α⊂page 142.␈α⊂ In␈α⊂the␈α⊂presence␈α⊂of␈α⊂a
␈↓ ↓H␈↓compiler␈α∩we␈α∩can␈α∩frequently␈α∪make␈α∩execution␈α∩of␈α∩macros␈α∪more␈α∩efficient␈α∩than␈α∩their␈α∪special␈α∩form
␈↓ ↓H␈↓counterpart.␈αThe␈αdistinction␈αis␈αthat␈αmacros␈αonly␈αinvolve␈αtransformations␈αwhich␈αcan␈αbe␈αexecuted␈αat
␈↓ ↓H␈↓␈↓↓6.19␈↓ λ↔Macros and Special Forms 337␈↓
␈↓ ↓H␈↓compile␈αtime,␈α
whereas␈αa␈αspecial␈α
form␈αmay␈αinvolve␈α
run␈αtime␈αinformation.␈α
For␈αexample,␈αconsider␈α
the
␈↓ ↓H␈↓case␈αof␈αthe␈αmacro␈αdefiniton␈αof␈α␈↓αplus␈↓.␈α When␈α␈↓αplus␈↓␈αis␈αcalled␈αwe␈αknow␈αthe␈αnumber␈αof␈αarguments,␈αand
␈↓ ↓H␈↓can simply expand the macro to a nest of calls on ␈↓α*plus␈↓. For example:
␈↓ ↓H␈↓α␈↓ βGplus[4;add1[2];4] ␈↓expands to␈↓α *plus[4;*plus[add1[2];4]] ␈↓
␈↓ ↓H␈↓which can be efficiently compiled.
␈↓ ↓H␈↓Macros␈αcan␈αalso␈αbe␈αused␈αeffectively␈αin␈αimplementing␈αabstract␈αdata␈αstructures␈αand␈αcontrol␈αstructures.
␈↓ ↓H␈↓For␈α∞example,␈α∞the␈α∞constructors,␈α∞selectors,␈α∞and␈α∞recognizers␈α∞which␈α∞help␈α∞characterize␈α∞a␈α∂data␈α∞structure
␈↓ ↓H␈↓can␈α∃be␈α∃expressed␈α∃as␈α∃very␈α∃simple␈α∀S-expr␈α∃operations.␈α∃ These␈α∃operations␈α∃are␈α∃performed␈α∀quite
␈↓ ↓H␈↓frequently␈α∂in␈α∂a␈α∞data␈α∂structure␈α∂algorithm␈α∞and␈α∂so␈α∂any␈α∞increase␈α∂in␈α∂their␈α∞running␈α∂efficiency␈α∂will␈α∞be
␈↓ ↓H␈↓beneficial.␈α Recall␈αthat␈αon␈αpage 71␈αwe␈αdefined␈α␈↓αcoef␈↓␈αas␈α␈↓αcar␈↓.␈αCompiled␈αcalls␈αon␈α␈↓αcoef␈↓␈αwould␈αinvoke␈αthe
␈↓ ↓H␈↓function-calling␈α
mechanism,␈α
whereas␈α
many␈αcompilers␈α
can␈α
substitute␈α
actual␈α
hardware␈αinstructions␈α
for
␈↓ ↓H␈↓calls␈α
on␈α
␈↓αcar␈↓,␈α
resulting␈α
in␈α
more␈α
efficient␈α
run-time␈α
code.␈α
It␈α
would␈α
be␈α
better␈α
to␈α
write␈α
␈↓αcar␈↓␈α
instead␈αof␈α
␈↓αcoef␈↓.
␈↓ ↓H␈↓There␈α
are␈αtwo␈α
objections␈αto␈α
this.␈α
First,␈α␈↓αcoef␈↓␈α
has␈αmore␈α
mnemonic␈α
significance␈αthan␈α
␈↓αcar␈↓.␈αSecond,␈α
using
␈↓ ↓H␈↓␈↓αcar␈↓␈αwe␈αhave␈αexplicitly␈αtied␈αour␈αalgorithm␈αto␈αthe␈αrepresentation.␈αBoth␈αare␈αstrong␈αobjections.␈α Macros
␈↓ ↓H␈↓can help overcome both objections. Define:
␈↓ ↓H␈↓␈↓ ¬∧␈↓αcoef <␈↓βm␈↓α= λ[[l] cons[CAR;cdr[l]]]␈↓.
␈↓ ↓H␈↓The␈αuser␈αwrites␈α␈↓α(COEF␈α...)␈↓;␈αthe␈αevaluator␈αsees␈α␈↓α(COEF␈α...)␈↓␈αand␈αevaluates␈α␈↓α(CAR␈α...)␈↓;␈αthe␈αcompiler␈αsees
␈↓ ↓H␈↓␈↓α(COEF␈α∩...)␈↓␈α∩and␈α∩compiles␈α∩code␈α∩for␈α∩␈↓α(CAR␈α∩...)␈↓.␈α∩With␈α∩macros,␈α∩we␈α∩can␈α∩get␈α∩the␈α∩efficient␈α∪code,␈α∩the
␈↓ ↓H␈↓readibility, and flexibility of representation.
␈↓ ↓H␈↓Macros␈α
can␈α
also␈α
be␈α
used␈α
to␈α
perform␈α
most␈αof␈α
the␈α
operations␈α
which␈α
special␈α
forms␈α
are␈α
meant␈α
to␈αdo.
␈↓ ↓H␈↓Since␈α␈↓αeval␈↓␈αhandles␈αcalls␈αon␈αspecial␈αforms,␈αwe␈αshould␈αexamine␈αthe␈αextensions␈αto␈α␈↓αcompile␈↓␈α
to␈αgenerate
␈↓ ↓H␈↓such␈αcode.␈αWe␈αhave␈α
seen␈αthat␈αin␈αcompiling␈αarguments␈α
to␈α(normal)␈αfunctions,␈αwe␈αgenerate␈α
the␈αcode
␈↓ ↓H␈↓for␈α
each,␈αfollowed␈α
by␈αcode␈α
to␈αsave␈α
the␈αresult␈α
in␈αthe␈α
run-time␈αstack,␈α
␈↓αP␈↓.␈α The␈α
argument␈αto␈α
a␈αspecial
␈↓ ↓H␈↓form␈α∞is␈α∞␈↓↓unevaluated␈↓,␈α∂by␈α∞definition.␈α∞All␈α∂we␈α∞can␈α∞thus␈α∂do␈α∞for␈α∞a␈α∞call␈α∂of␈α∞the␈α∞form␈α∂␈↓αf[l]␈↓,␈α∞where␈α∞␈↓αf␈↓␈α∂is␈α∞a
␈↓ ↓H␈↓special form, is pass the argument, compiling something like:
␈↓ ↓H␈↓α␈↓ ¬1(MOVEI AC1 (␈↓
R␈↓∞(␈↓α l ␈↓∞)␈↓α))
␈↓ ↓H␈↓α␈↓ ¬h(CALL 1 (E F))
␈↓ ↓H␈↓We␈α
have␈α
already␈α
mentioned␈α
some␈α
of␈α
the␈α∞dangers␈α
in␈α
using␈α
special␈α
forms;␈α
the␈α
fact␈α
that␈α∞a␈α
compiler
␈↓ ↓H␈↓cannot do much with them either, makes them even less attractive.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I. Extend the last ␈↓αcompile␈↓ function to handle macros.
␈↓ ↓H␈↓␈↓↓338 Dynamic Structure␈↓ )6.19␈↓
␈↓ ↓H␈↓II.␈α∩Assume␈α∩␈↓αand␈↓␈α∩allows␈α∪an␈α∩indefinite␈α∩number␈α∩of␈α∩arguments.␈α∪ Show␈α∩how␈α∩to␈α∩modify␈α∪␈↓αcompile␈↓␈α∩to
␈↓ ↓H␈↓recognize ␈↓αand␈↓ and compile efficient code for its execution.
␈↓ ↓H␈↓III.␈α∞Define␈α∞␈↓αand␈↓␈α
as␈α∞a␈α∞macro␈α
in␈α∞terms␈α∞of␈α
␈↓αcond␈↓.␈α∞Compare␈α∞the␈α
code␈α∞produced␈α∞in␈α
the␈α∞two␈α∞cases.␈α
How
␈↓ ↓H␈↓could you improve the compiler to make the two sets of code more nearly alike?
␈↓ ↓H␈↓␈↓ ∧r␈↓↓6.20 Compilation and Variables␈↓
␈↓ ↓H␈↓The␈α
models␈α
of␈α
compilation␈αwhich␈α
we␈α
have␈α
sketched␈αso␈α
far␈α
store␈α
their␈αλ-variables␈α
in␈α
the␈α
stack,␈α␈↓αP␈↓.
␈↓ ↓H␈↓References␈αto␈αthose␈αvariables␈αin␈αthe␈αbody␈αof␈α
the␈αλ-expression␈αare␈αmade␈αto␈αthose␈αstack␈αentries.␈α
This
␈↓ ↓H␈↓scheme␈α
suffices␈α
only␈α
for␈α
lambda␈αor␈α
␈↓αprog␈↓␈α
variables␈α
which␈α
are␈αused␈α
in␈α
a␈α
strictly␈α
local␈α
fashion.␈α We
␈↓ ↓H␈↓have␈αsaid␈αthat␈αλ-expressions␈αmay␈αrefer␈αto␈αglobal␈αor␈αfree␈αvariables.␈α The␈αlookup␈αmechanism␈αsimply
␈↓ ↓H␈↓finds␈α
the␈αlatest␈α
binding␈α
of␈αthat␈α
variable␈αin␈α
the␈α
current␈αsymbol␈α
table;␈α
this␈αis␈α
LISP's␈αdynamic␈α
binding
␈↓ ↓H␈↓strategy.␈α∞ There␈α∞are␈α∞potential␈α∞difficulties␈α∂for␈α∞compiled␈α∞code␈α∞when␈α∞dealing␈α∞with␈α∂dynamic␈α∞binding.
␈↓ ↓H␈↓The␈α
problem␈αinvolves␈α
reference␈αto␈α
variables␈αwhich␈α
are␈αcurrently␈α
λ-bound␈αbut␈α
are␈α
non-local.␈αSuch
␈↓ ↓H␈↓variables are called ␈↓↓special variables␈↓.
␈↓ ↓H␈↓Assume␈αfirst,␈αthat␈αwe␈αare␈αattempting␈αa␈αdeep␈αbinding␈αimplementation.␈αIf␈αall␈αwe␈αstore␈αon␈αthe␈αstack␈αis
␈↓ ↓H␈↓the␈αvalue␈αof␈αa␈α
variable,␈αthen␈αanother␈αprogram␈αwhich␈α
expects␈αto␈αuse␈αthat␈α
value␈αwill␈αhave␈αno␈αway␈α
of
␈↓ ↓H␈↓finding␈αthat␈αstored␈αvalue.␈α One␈αscheme␈αis␈αto␈αstore␈αpairs␈αon␈αthe␈αstack:␈αname␈αand␈αvalue,␈αthen␈αwe␈αcan
␈↓ ↓H␈↓search␈α
the␈αstack␈α
for␈αthe␈α
latest␈α
binding.␈α This␈α
scheme␈αis␈α
compatible␈α
with␈αthe␈α
stack␈αimplementation␈α
of
␈↓ ↓H␈↓deep␈αbinding␈αgiven␈αin␈αSection 5.18.␈α The␈αcompiler␈αcan␈αstill␈α`know'␈αwhere␈αall␈αthe␈αlocal␈αvariables␈αare
␈↓ ↓H␈↓on the stack and can be a bit clever about searching for the globals or special variables.
␈↓ ↓H␈↓Shallow␈αbinding␈αimplementations␈αoffer␈αan␈αalternative.␈αWe␈αcan␈αstill␈αstore␈αvariables␈αon␈αthe␈αstack␈↓π 215␈↓
␈↓ ↓H␈↓if␈αwe␈α
are␈αsure␈α
that␈αthe␈αvariable␈α
is␈αused␈α
in␈αa␈αstrictly␈α
local␈αfashion.␈α
If␈αa␈αvariable␈α
is␈αto␈α
be␈αused␈α
as␈αa
␈↓ ↓H␈↓special␈αvariable␈αthen␈αthe␈αcompiled␈α
code␈αshould␈αaccess␈αthe␈αvalue␈α
cell␈αof␈αthat␈αvariable.␈α The␈α
compiler
␈↓ ↓H␈↓recognizes␈αa␈αvariable␈αas␈αspecial␈αby␈αlooking␈αfor␈αthe␈αproperty␈αname␈α␈↓αSPECIAL␈↓␈αon␈αthe␈αproperty␈αlist␈αof
␈↓ ↓H␈↓the␈α
atom;␈α
if␈α
the␈α∞property␈α
exists␈α
and␈α
its␈α
value␈α∞is␈α
␈↓
t␈↓␈α
then␈α
the␈α
variable␈α∞is␈α
a␈α
special␈α
variable␈α∞and␈α
the
␈↓ ↓H␈↓compiler␈α
generates␈α
different␈α
code.␈α When␈α
a␈α
variable,␈α
say␈α
␈↓αx␈↓,␈αis␈α
declared␈α
special␈α
the␈α
compiler␈αwill␈α
emit
␈↓ ↓H␈↓a␈α
reference␈αto␈α
␈↓αx␈↓␈αas␈α
␈↓α(GETV AC␈↓βi␈↓α X)␈↓␈α
or␈α␈↓α(PUTV AC␈↓βi␈↓α X)␈↓␈α
rather␈αthan␈α
the␈αcorresponding␈α
reference␈α
to␈αa
␈↓ ↓H␈↓location␈α∞on␈α∞the␈α∞stack.␈α
␈↓αGETV␈↓␈α∞and␈α∞␈↓αPUTV␈↓␈α∞are␈α
instructions␈α∞to␈α∞access␈α∞or␈α
modify␈α∞the␈α∞contents␈α∞of␈α
the
␈↓ ↓H␈↓value cell.
␈↓ ↓H␈↓When␈α
the␈α
LISP␈α∞assembler␈α
sees␈α
one␈α∞of␈α
these␈α
instructions,␈α∞it␈α
will␈α
locate␈α∞the␈α
value cell␈α
of␈α∞atom␈α
and
␈↓ ↓H␈↓assemble␈α⊂a␈α⊂reference␈α⊂to␈α∂that␈α⊂cell.␈α⊂ Since␈α⊂the␈α∂location␈α⊂of␈α⊂the␈α⊂value cell␈α∂does␈α⊂␈↓↓not␈↓␈α⊂change,␈α⊂we␈α∂can
␈↓ ↓H␈↓always␈α∪find␈α∪the␈α∪current␈α∪binding.␈α∪Any␈α∪interpreted␈α∪function␈α∪can␈α∪also␈α∪sample␈α∪the␈α∀value cell␈α∪so
␈↓ ↓H␈↓non-local values can be passed between compiled and interpreted functions.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 215␈↓␈α
We␈αassume␈α
throughout␈α
this␈αdiscussion␈α
that␈α
we␈αare␈α
compiling␈α
code␈αfor␈α
the␈αstack␈α
implementation
␈↓ ↓H␈↓of shallow binding as given in Section 5.19.
␈↓ ↓H␈↓␈↓↓6.20␈↓ λβCompilation and Variables 339␈↓
␈↓ ↓H␈↓Non-local␈αvariables,␈αtherefore␈αnecessitate␈αsome␈αchanges␈αto␈αour␈αcompiler:␈αwe␈αhave␈αto␈αbe␈αa␈αbit␈αcareful
␈↓ ↓H␈↓in␈αdealing␈α
with␈αspecial␈αvariables.␈α
Assume␈αa␈αfunction␈α
␈↓αf␈↓␈αcalls␈αa␈α
function␈α␈↓αg␈↓,␈αand␈α
assume␈αthat␈α
␈↓αg␈↓␈αuses
␈↓ ↓H␈↓some␈αof␈α␈↓αf␈↓'s␈αλ-variables.␈α The␈α
usual␈αcompilation␈αfor␈α␈↓αf␈↓␈αwould␈α
place␈αthe␈αλ-variables␈αin␈αthe␈α
stack␈αand
␈↓ ↓H␈↓they␈α
would␈α
not␈α
be␈α
accessible␈α
to␈α
␈↓αg␈↓.␈α
Our␈α
compiler␈α
must␈α
therefore␈α
be␈α
modified␈α
to␈α∞generate␈α
different
␈↓ ↓H␈↓prolog␈αand␈αepilog␈αcode␈αfor␈α
special␈αvariables.␈α The␈αcode␈αmust␈α
save␈αthe␈αold␈αcontents␈αof␈α
each␈αspecial
␈↓ ↓H␈↓value cell␈α∞on␈α∞entry␈α∞to␈α∞the␈α∞function,␈α∞and␈α∂the␈α∞compiler␈α∞must␈α∞generate␈α∞code␈α∞to␈α∞restore␈α∞those␈α∂cells␈α∞at
␈↓ ↓H␈↓function␈αexit.␈α As␈αwe␈αdescribed␈αabove,␈αany␈αreferences␈αin␈αeither␈α␈↓αf␈↓␈αor␈α␈↓αg␈↓␈αto␈αthose␈αspecial␈αvariables␈α
will
␈↓ ↓H␈↓involve␈α␈↓αGETV-PUTV␈↓␈α
rather␈αthan␈α
references␈αinto␈α
the␈αstack␈α
␈↓αP␈↓.␈αIn␈α
this␈αscheme,␈α
␈↓αlookup[x;env]␈↓␈αis␈α
given
␈↓ ↓H␈↓by ␈↓αgetv[x]␈↓.
␈↓ ↓H␈↓Non-local␈α↔variables␈α↔cause␈α↔several␈α⊗problems␈α↔in␈α↔LISP.␈α↔The␈α⊗simple␈α↔mechanism␈α↔we␈α↔used␈α⊗for
␈↓ ↓H␈↓referencing␈αlocal␈αvariables␈αis␈αno␈αlonger␈αapplicable.␈αOther␈αprogramming␈αlanguages␈αallow␈αthe␈αuse␈αof
␈↓ ↓H␈↓non-local␈αvariables,␈αsome,␈αlike␈αAPL␈α([Ive 62]),␈αonly␈αallow␈αglobal␈αvariables;␈αothers,␈αlike␈αAlgol60␈αand
␈↓ ↓H␈↓its␈α∩successors␈α∩([Alg 63]␈α∩and␈α∩[Alg 75]),␈α∩allow␈α∩free␈α∩as␈α∩well␈α∩as␈α∩global␈α∩variables.␈α∩ However,␈α∩Algol
␈↓ ↓H␈↓compilers␈αare␈α
much␈αsimpler␈αto␈α
construct␈αthan␈αLISP␈α
compilers,␈αand␈αwe␈α
should␈αexplore␈αsome␈α
of␈αthe
␈↓ ↓H␈↓reasons␈↓π 216␈↓.␈α
One␈α
simplicity␈α
of␈α
Algol␈α
is␈αits␈α
treatment␈α
of␈α
procedure␈α
valued␈α
variables.␈α
Algol␈αdialects
␈↓ ↓H␈↓typically␈α∞restrict␈α∞themselves␈α∞to␈α∞what␈α∞LISP␈α∂calls␈α∞functional␈α∞arguments.␈α∞Algol␈α∞dialects␈α∞do␈α∂not␈α∞allow
␈↓ ↓H␈↓arbitrary␈α
procedures␈αto␈α
be␈αreturned␈α
as␈αvalues.␈α
Their␈α
restrictions␈αallow␈α
the␈αrun␈α
time␈αenvironment␈α
to
␈↓ ↓H␈↓modelled in a stack, typically as described in Section 5.18.
␈↓ ↓H␈↓The␈α∪difference␈α∪between␈α∩LISP␈α∪and␈α∪Algol,␈α∪which␈α∩is␈α∪more␈α∪to␈α∪the␈α∩point␈α∪here,␈α∪is␈α∪their␈α∩binding
␈↓ ↓H␈↓strategies (Section 3.11).␈α∞A␈α∂typical␈α∞LISP␈α∞uses␈α∂dynamic␈α∞binding␈α∞whereas␈α∂Algol␈α∞uses␈α∂static␈α∞binding.
␈↓ ↓H␈↓The␈α∩difference␈α∪is␈α∩that␈α∪Algol␈α∩translators␈α∪determine␈α∩the␈α∩bindings␈α∪of␈α∩variables␈α∪at␈α∩the␈α∪time␈α∩the
␈↓ ↓H␈↓definition␈αis␈αmade␈αwhereas␈αLISP␈αdetermines␈αbindings␈αat␈αthe␈αtime␈αthe␈αfunction␈αis␈αapplied.␈α That␈αis,
␈↓ ↓H␈↓definitions␈α∂in␈α∞Algol␈α∂always␈α∂imply␈α∞an␈α∂application␈α∞of␈α∂␈↓αfunction␈↓,␈α∂binding␈α∞up␈α∂all␈α∂non-local␈α∞variables.
␈↓ ↓H␈↓The␈α⊂net␈α⊂effect␈α∂is␈α⊂that␈α⊂Algol␈α∂don't␈α⊂have␈α⊂free␈α∂variables␈α⊂in␈α⊂the␈α∂sense␈α⊂that␈α⊂there␈α∂is␈α⊂any␈α⊂choice␈α∂of
␈↓ ↓H␈↓bindings;␈α∂all␈α∂choices␈α∂have␈α∞been␈α∂made␈α∂when␈α∂a␈α∂procedure␈α∞is␈α∂declared.␈α∂That␈α∂binding␈α∂decision␈α∞has
␈↓ ↓H␈↓dramatic␈αresults␈αwhen␈αwe␈αcome␈αto␈αimplement␈α
language␈αtranslators.␈αAs␈αa␈αresult,␈αAlgol␈αcan␈α
effectively
␈↓ ↓H␈↓compile␈α∞all␈α∞variable␈α∂references␈α∞to␈α∞be␈α∞references␈α∂into␈α∞the␈α∞run␈α∞time␈α∂stack,␈α∞and␈α∞need␈α∞not␈α∂retain␈α∞the
␈↓ ↓H␈↓name␈αstack␈α
for␈αvariable␈α
look␈αup␈αat␈α
run␈αtime.␈α
It␈αis␈α
not␈αat␈αall␈α
clear␈αyet␈α
which␈αbinding␈α
strategy␈αwill
␈↓ ↓H␈↓dominate.␈α∀Counterexamples␈α∀to␈α∀exclusive␈α∀use␈α∃of␈α∀either␈α∀strategy␈α∀exist.␈α∀Recent␈α∃work␈α∀([Ste 76b],
␈↓ ↓H␈↓[Sus 75], [Hew 76]) points to the use of static binding in LISP-like languages.
␈↓ ↓H␈↓A␈α∂typical␈α∂preserve␈α∂of␈α∂dynamic␈α∂binding␈α∂is␈α∂that␈α∂of␈α∂interactive␈α∂programming,␈α∂where␈α∂programs␈α∞are
␈↓ ↓H␈↓created␈αas␈α
separate␈αentities␈α
to␈αbe␈α
connected␈αinto␈αa␈α
cohesive␈αwhole␈α
at␈αsome␈α
later␈αtime.␈αFrequently␈α
one
␈↓ ↓H␈↓wants the bindings of the free varaibles to be postponed until such a grouping is made.
␈↓ ↓H␈↓␈↓ ¬α␈↓↓6.21 Interactive Programming␈↓
␈↓ ↓H␈↓␈↓ ∧λ"...␈α
What␈α
is␈αactually␈α
happening,␈α
I␈α
am␈αafraid,␈α
is␈α
that␈αwe␈α
all␈α
tell␈α
each␈αother
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 216␈↓ For reasons other than those we are addressing here, APL compilers are difficult to construct.
␈↓ ↓H␈↓␈↓↓340 Dynamic Structure␈↓ )6.21␈↓
␈↓ ↓H␈↓␈↓ ∧λand␈α⊂ourselves␈α⊂that␈α⊂software␈α∂engineering␈α⊂techniques␈α⊂should␈α⊂be␈α∂improved
␈↓ ↓H␈↓␈↓ ∧λconsiderably,␈α∪because␈α∩there␈α∪is␈α∪a␈α∩crisis.␈α∪But␈α∪there␈α∩are␈α∪a␈α∪few␈α∩boundary
␈↓ ↓H␈↓␈↓ ∧λconditions which apparently have to be satisfied. I will list them for you:
␈↓ ↓H␈↓␈↓ ∧λ␈↓↓1.␈↓ We may not change our thinking habits.
␈↓ ↓H␈↓␈↓ ∧λ␈↓↓2.␈↓ We may not change our programming tools.
␈↓ ↓H␈↓␈↓ ∧λ␈↓↓3.␈↓ We may not change our hardware.
␈↓ ↓H␈↓␈↓ ∧λ␈↓↓4.␈↓ We may not change our tasks.
␈↓ ↓H␈↓␈↓ ∧λ␈↓↓5.␈↓␈αWe␈αmay␈αnot␈αchange␈αthe␈αorganizational␈αset-up␈αin␈αwhich␈αthe␈αwork␈αhas␈αto
␈↓ ↓H␈↓␈↓ ∧λbe done.
␈↓ ↓H␈↓␈↓ ∧λNow␈α∞under␈α
these␈α∞five␈α
immutable␈α∞boundary␈α
conditions,␈α∞we␈α
have␈α∞to␈α∞try␈α
to
␈↓ ↓H␈↓␈↓ ∧λimprove matters. This is utterly ridiculous. Thank you. (␈↓αApplause␈↓).
␈↓ ↓H␈↓␈↓ ε≠E. Dijkstra, ␈↓αConference of Software Engineering, 1968␈↓.
␈↓ ↓H␈↓We␈αhave␈αtalked␈αabout␈αthe␈αconstructs␈αof␈αLISP;␈αwe␈αhave␈αtalked␈αabout␈αinterpreters␈αand␈αcompilers␈αfor
␈↓ ↓H␈↓LISP;␈α⊂and␈α⊃we␈α⊂have␈α⊃talked␈α⊂a␈α⊃little␈α⊂about␈α⊃input␈α⊂and␈α⊃output␈α⊂conventions␈α⊃for␈α⊂the␈α⊃language.␈α⊂The
␈↓ ↓H␈↓combination␈α∩of␈α∩these␈α∪properties␈α∩leads␈α∩us␈α∩to␈α∪a␈α∩most␈α∩interesting␈α∩practical␈α∪aspect␈α∩of␈α∩LISP␈α∪as␈α∩a
␈↓ ↓H␈↓programing␈αlanguage:␈αits␈αuse␈αas␈αan␈αinteractive␈αprogramming␈αlanguage.␈αA␈αprogramming␈αlanguage␈α
is
␈↓ ↓H␈↓a␈α
tool␈αfor␈α
building␈α
programs.␈αLISP's␈α
representation␈α
of␈αprograms␈α
as␈α
data␈αstructures␈α
coupled␈αwith␈α
the
␈↓ ↓H␈↓availablilty␈α⊗of␈α⊗display␈α∃terminals␈α⊗offers␈α⊗the␈α⊗LISP␈α∃programmer␈α⊗unique␈α⊗opportunities␈α⊗for␈α∃the
␈↓ ↓H␈↓interactive␈αconstruction␈αof␈αprograms.␈α Historically,␈αmachines␈αhave␈αbeen␈αoriented␈αtowards␈α
the␈αrapid
␈↓ ↓H␈↓execution of well-defined numerical algorithms. This perspective over-looks two important points.
␈↓ ↓H␈↓First,␈αthe␈αactual␈αprocess␈αof␈αdiscovering,␈αrefining,␈αand␈αencoding␈αthe␈αalgorithm␈αis␈αa␈α
complex␈αprocess.
␈↓ ↓H␈↓In␈α∂the␈α⊂early␈α∂days␈α⊂of␈α∂computation,␈α⊂the␈α∂programmer␈α∂performed␈α⊂the␈α∂analysis␈α⊂on␈α∂the␈α⊂algorithm␈α∂on
␈↓ ↓H␈↓paper,␈α⊂transcribed␈α⊂the␈α⊂algorithm␈α⊂to␈α⊂a␈α∂programming␈α⊂language,␈α⊂encoded␈α⊂that␈α⊂program␈α⊂on␈α∂coding
␈↓ ↓H␈↓sheets␈αand␈αkeypunched␈αa␈αcard␈αdeck.␈αThat␈αdeck␈αwas␈αsupplied␈αwith␈αdata␈αcards␈αand␈αpresented␈αto␈αthe
␈↓ ↓H␈↓machine.␈α If␈αsome␈αabnormal␈αbehavior␈αwas␈αdetected␈αin␈αyour␈αprogram,␈αyou␈αwere␈αalso␈αpresented␈αwith
␈↓ ↓H␈↓an␈α∃uninspiring␈α∃octal␈α∃dump␈α∃of␈α∃the␈α∃contents␈α∃of␈α∃memory.␈α∃Memory␈α∃dumps␈α∃were␈α∃an␈α∀appalling
␈↓ ↓H␈↓debugging␈αtechnique,␈αeven␈αthen.␈α Programming␈αwas␈αfrequently␈αdone␈αin␈αa␈αhigher␈αlevel␈αlanguage␈αso
␈↓ ↓H␈↓the␈αcontents␈αof␈αmost␈αmachine␈αlocations␈αhad␈αlittle␈αmeaning␈αto␈αthe␈αprogrammer.␈αAlso␈αthe␈αstate␈αof␈αthe
␈↓ ↓H␈↓machine␈αat␈αthe␈αtime␈αthe␈αdump␈αwas␈αtaken␈αfrequently␈αhad␈αonly␈αa␈αcasual␈αrelationship␈αwith␈αthe␈αactual
␈↓ ↓H␈↓bug.
␈↓ ↓H␈↓The␈α∂programmer␈α∞had␈α∂a␈α∂slightly␈α∞more␈α∂appealing␈α∞alternative␈α∂called␈α∂␈↓↓tracing␈↓.␈α∞A␈α∂program␈α∂could␈α∞be
␈↓ ↓H␈↓embellished␈α⊂with␈α⊂print␈α⊂statements␈α∂whose␈α⊂purpose␈α⊂was␈α⊂to␈α∂determine␈α⊂access␈α⊂behavior␈α⊂by␈α∂printing
␈↓ ↓H␈↓values␈αof␈α
variables,␈αand␈α
to␈αdiscover␈αcontrol␈α
behavior␈αby␈α
printing␈αmessages␈αat␈α
entry␈αand␈α
exit␈αfrom
␈↓ ↓H␈↓procedures.␈α
This␈αtracing␈α
technique␈αwas␈α
frequently␈αavailable␈α
as␈αan␈α
operating␈αsystem␈α
option.␈αThen
␈↓ ↓H␈↓the␈αprogrammer␈α
would␈αsupply␈αcontrol␈α
cards␈αwhich␈αexpressed␈α
what␈αkind␈αof␈α
output␈αwas␈α
desired.␈αIn
␈↓ ↓H␈↓␈↓↓6.21␈↓ λ Interactive Programming 341␈↓
␈↓ ↓H␈↓either␈α⊂case,␈α⊃unless␈α⊂this␈α⊂technique␈α⊃was␈α⊂used␈α⊂with␈α⊃resolute␈α⊂precision,␈α⊂the␈α⊃output␈α⊂would␈α⊃either␈α⊂be
␈↓ ↓H␈↓voluminous or uninformative, or both.
␈↓ ↓H␈↓When␈α∂the␈α∂cause␈α⊂of␈α∂a␈α∂bug␈α∂was␈α⊂discovered␈α∂the␈α∂offending␈α∂cards␈α⊂were␈α∂replaced␈α∂and␈α∂the␈α⊂deck␈α∂was
␈↓ ↓H␈↓resubmitted␈α⊂for␈α∂execution.␈α⊂This␈α∂cycle␈α⊂was␈α⊂repeated␈α∂until␈α⊂an␈α∂acceptable␈α⊂program␈α⊂was␈α∂developed.
␈↓ ↓H␈↓This␈αapproach␈αis␈αstill␈αfollowed␈αby␈αa␈αmajority␈αof␈αprogrammers.␈αWhat␈αis␈αmissed␈αis␈αthat␈αmuch␈αof␈αthe
␈↓ ↓H␈↓detail␈α
and␈αtedium␈α
of␈αthese␈α
early␈αphases␈α
of␈αprogram␈α
development␈αcan␈α
be␈αaided␈α
by␈αa␈α
well-constructed
␈↓ ↓H␈↓interactive programming system.
␈↓ ↓H␈↓The␈αsecond␈αpoint␈αwhich␈αis␈αoverlooked␈αis␈αthat␈αa␈αlarge␈αclass␈αof␈αinteresting␈αproblems␈αare␈αnot␈αincluded
␈↓ ↓H␈↓in␈α⊃the␈α⊃range␈α⊃of␈α⊃"well-defined␈α⊃numerical␈α∩algorithms".␈α⊃ In␈α⊃fact␈α⊃most␈α⊃of␈α⊃the␈α⊃problems␈α∩which␈α⊃are
␈↓ ↓H␈↓traditionally␈α⊂attacked␈α⊃by␈α⊂LISP␈α⊂programs␈α⊃fall␈α⊂into␈α⊂this␈α⊃class:␈α⊂language␈α⊂design,␈α⊃theorem␈α⊂proving,
␈↓ ↓H␈↓compiler␈α
writing,␈αand␈α
of␈αcourse,␈α
artificial␈αintelligence.␈α
In␈αsuch␈α
"exploratory␈αprogramming"␈α
it␈αis␈α
often
␈↓ ↓H␈↓the␈α∞case␈α∞that␈α∞no␈α∞well-defined␈α∞algorithm␈α∞is␈α∞known,␈α
and␈α∞it␈α∞will␈α∞be␈α∞the␈α∞final␈α∞program␈α∞which␈α∞␈↓↓is␈↓␈α
the
␈↓ ↓H␈↓algorithm.␈αSuch␈αexploratory␈αprogramming␈αrequires␈αthat␈αthe␈αprogramming␈αlanguage␈αbe␈αusable␈αas␈αa
␈↓ ↓H␈↓sophisticated␈α⊗"desk␈α⊗calculator".␈α∃It␈α⊗requires␈α⊗experimentation␈α∃with,␈α⊗and␈α⊗execution␈α⊗of,␈α∃partially
␈↓ ↓H␈↓specified␈αprograms;␈αthat␈αis␈αthe␈αability␈αto␈αdevelop␈αand␈αrun␈αpieces␈αof␈αprograms;␈αto␈αbuild␈αup␈αa␈αlarger
␈↓ ↓H␈↓program␈α∩from␈α∩pieces;␈α∩to␈α∩quickly␈α∩modify␈α∩either␈α∩the␈α∩program␈α∩text␈α∩or␈α∩the␈α∩computational␈α∩results
␈↓ ↓H␈↓themselves, before the programmers have lost their train of thought.
␈↓ ↓H␈↓An␈αimportant␈αoutgrowth␈αof␈αsuch␈αexploratory␈α
programming␈αis␈αa␈αLISP␈αtechnique␈αcalled␈α
"throw-away
␈↓ ↓H␈↓implementation".␈α∞In␈α∞developing␈α∞a␈α∂large␈α∞programming␈α∞system␈α∞one␈α∂begins␈α∞with␈α∞a␈α∞few␈α∂simple␈α∞ideas
␈↓ ↓H␈↓and␈α∪incrementally␈α∩develops␈α∪the␈α∩larger␈α∪system.␈α∪ If␈α∩some␈α∪of␈α∩the␈α∪ideas␈α∩are␈α∪inadequate␈α∪they␈α∩are
␈↓ ↓H␈↓replaced.␈αAt␈αsome␈αstage␈αan␈αadequate␈αmodel␈αis␈α
developed;␈αit␈αmay␈αbe␈αlacking␈αin␈αsome␈αaspects,␈α
but␈αit
␈↓ ↓H␈↓does␈α⊂model␈α⊃the␈α⊂desired␈α⊂phenomenon.␈α⊃At␈α⊂that␈α⊂point,␈α⊃the␈α⊂programmer's␈α⊂understanding␈α⊃has␈α⊂been
␈↓ ↓H␈↓sufficiently␈α↔improved,␈α↔that␈α↔the␈α↔implementation␈α↔should␈α↔be␈α↔thrown␈α↔away␈α↔and␈α↔a␈α_new,␈α↔more
␈↓ ↓H␈↓enlightened␈α∪version,␈α∪created.␈α∀ Certainly␈α∪this␈α∪kind␈α∪of␈α∀programming␈α∪can␈α∪be␈α∀accomplished␈α∪with
␈↓ ↓H␈↓languages␈α∩other␈α∩than␈α∩LISP;␈α∩the␈α∩point␈α∩is␈α∩that␈α∩an␈α∩interactive␈α∩LISP␈α∩environment␈α∩is␈α⊃sufficiently
␈↓ ↓H␈↓responsive␈αthat␈αan␈αimplementation␈αcycle␈α
is␈αquite␈αshort␈αand␈αrelatively␈α
painless.␈αThe␈αeffect␈αis␈αthat␈α
the
␈↓ ↓H␈↓programmer␈α∞does␈α∂not␈α∞invest␈α∂so␈α∞much␈α∂effort␈α∞in␈α∂an␈α∞implementation␈α∂that␈α∞he␈α∂feels␈α∞a␈α∂compulsion␈α∞to
␈↓ ↓H␈↓patch an inferior implementation, rather than start afresh.
␈↓ ↓H␈↓The␈α∞development␈α∞of␈α∞an␈α∞interactive␈α∞programming␈α∞system␈α∞has␈α∞several␈α∞important␈α∞implications.␈α∞The
␈↓ ↓H␈↓usual␈α∩partitioning␈α∩of␈α∩program␈α∩preparation␈α∩into␈α∩editing,␈α∩running,␈α∩and␈α∩debugging␈α∩is␈α∪no␈α∩longer
␈↓ ↓H␈↓adequate.␈α⊃The␈α⊃text␈α⊂editor␈α⊃and␈α⊃the␈α⊃debugger␈α⊂are␈α⊃integral␈α⊃parts␈α⊂of␈α⊃the␈α⊃system.␈α⊃A␈α⊂programming
␈↓ ↓H␈↓"environment"␈α
is␈α∞established␈α
in␈α
which␈α∞all␈α
facets␈α∞of␈α
programming␈α
are␈α∞integrated.␈α
The␈α∞tasks␈α
which
␈↓ ↓H␈↓are␈α
usually␈α
performed␈α
by␈α
an␈α
operating␈αsystem␈α
are␈α
subsumed␈α
by␈α
the␈α
programming␈α
language.␈α The
␈↓ ↓H␈↓idea␈α∂of␈α⊂a␈α∂separate␈α⊂file␈α∂system␈α⊂becomes␈α∂obsolete,␈α⊂and␈α∂all␈α⊂programs␈α∂and␈α⊂data␈α∂are␈α⊂accessible␈α∂from
␈↓ ↓H␈↓within␈α∀the␈α∀"environment".␈α∪This␈α∀has␈α∀an␈α∀important␈α∪advantage␈α∀in␈α∀LISP-like␈α∀representations␈α∪of
␈↓ ↓H␈↓programs:␈α∩the␈α∩conversion␈α⊃from␈α∩internal␈α∩representation␈α⊃to␈α∩"text␈α∩file"␈α⊃format␈α∩is␈α∩eliminated.␈α⊃The
␈↓ ↓H␈↓technique␈αputs␈α
added␈αburden␈αon␈α
naming␈αfacilities␈α
so␈αthat␈αa␈α
programmer's␈αdefinitions␈αare␈α
accessible,
␈↓ ↓H␈↓but␈αare␈αunambigiously␈αaddressible.␈α The␈αeffect␈αis␈α
to␈αstructure␈αthe␈αinteractive␈αenvironment␈αas␈αa␈α
very
␈↓ ↓H␈↓large␈α
data␈α
base␈α
containing␈α
programs␈α
and␈α
data␈α
structures.␈α
The␈α
programmer␈α
has␈α
accessing␈α
procedures
␈↓ ↓H␈↓to␈αmanipulate␈α
the␈αelements␈α
in␈αthe␈α
base.␈αAll␈α
the␈αitems␈α
in␈αthe␈α
base␈αare␈α
accessible␈αas␈α
data␈αstructures;
␈↓ ↓H␈↓the␈αeditor␈αcan␈αmodify␈αany␈αobjects␈αin␈αthe␈αbase.␈α Some␈αof␈αthe␈αobjects␈αcan␈αbe␈αexecuted␈αas␈αprocedures;
␈↓ ↓H␈↓␈↓↓342 Dynamic Structure␈↓ )6.21␈↓
␈↓ ↓H␈↓the␈α∞evaluator␈α∂is␈α∞responsible␈α∂for␈α∞this.␈α∂A␈α∞procedure␈α∞object␈α∂can␈α∞be␈α∂further␈α∞expanded␈α∂into␈α∞machine
␈↓ ↓H␈↓instructions␈αfor␈αfaster␈α
execution;␈αthis␈αmay␈α
either␈αbe␈αdone␈αby␈α
an␈αexplicit␈αcall␈α
on␈αa␈αcompiler,␈αor␈α
better
␈↓ ↓H␈↓yet,␈αbe␈αdone␈αinvisibly␈αby␈αa␈αcompiler/interpreter.␈αIf␈αan␈αevaluation␈αis␈αnot␈αperforming␈αas␈αexpected,␈αyet
␈↓ ↓H␈↓another␈α∂data␈α∂structure␈α∂manipulating␈α∂program␈α∂is␈α∂available.␈α∂ The␈α∂debugger␈α∂is␈α∂able␈α∂to␈α∂manipulate
␈↓ ↓H␈↓both␈αthe␈αprogram␈αstructure␈αand␈αthe␈αrun time␈αdata␈αstructures␈αwhich␈αthe␈αevaluator␈αhas␈αcreated.␈αAny
␈↓ ↓H␈↓of␈α∂these␈α∂data␈α⊂structure␈α∂manipulating␈α∂programs␈α∂is␈α⊂able␈α∂to␈α∂call␈α∂any␈α⊂other␈α∂program.␈α∂This␈α⊂view␈α∂of
␈↓ ↓H␈↓program␈α⊃development␈α⊃is␈α⊃in␈α⊂direct␈α⊃conflict␈α⊃with␈α⊃the␈α⊂traditional␈α⊃approach␈α⊃which␈α⊃grew␈α⊃from␈α⊂the
␈↓ ↓H␈↓card deck␈α∞philosophy.␈α∞ Several␈α∞current␈α∞research␈α∂projects␈α∞are␈α∞developing␈α∞along␈α∞these␈α∂lines;␈α∞among
␈↓ ↓H␈↓them are [Hew 75], [Int 75], and [Win 75]. All of these projects are based on LISP.
␈↓ ↓H␈↓It␈αis␈αnot␈αaccidental␈αthat␈αLISP␈αis␈αthe␈αmajor␈αlanguage␈αfor␈αthese␈αkinds␈αof␈αprogramming␈αtasks;␈αit␈αis␈αthe
␈↓ ↓H␈↓features␈α⊂of␈α∂the␈α⊂language␈α⊂which␈α∂make␈α⊂it␈α∂amenable␈α⊂to␈α⊂such␈α∂programming␈α⊂tasks.␈α∂In␈α⊂the␈α⊂next␈α∂two
␈↓ ↓H␈↓sections␈α∪we␈α∪will␈α∪discuss␈α∀two␈α∪of␈α∪the␈α∪ingredients␈α∀of␈α∪interactive␈α∪programming␈α∪systems;␈α∀this␈α∪will
␈↓ ↓H␈↓illuminate the features of LISP which make it important for interactive programming.
␈↓ ↓H␈↓First␈αwe␈α
will␈αsketch␈α
some␈αbasic␈α
features␈αof␈α
LISP␈αtext␈α
editors.␈αThis␈α
will␈αshow␈α
some␈αof␈α
the␈αbenefits␈α
of
␈↓ ↓H␈↓having␈α
the␈α
program␈α∞structure␈α
available␈α
as␈α∞a␈α
data␈α
structure.␈α
The␈α∞succeeding␈α
section␈α
will␈α∞discuss␈α
a
␈↓ ↓H␈↓few␈α
features␈α
of␈α
a␈α
typical␈α
LISP␈α∞debugging␈α
system;␈α
this␈α
will␈α
further␈α
demonstrate␈α
the␈α∞advantages␈α
of
␈↓ ↓H␈↓having a natural program representation available at run time.
␈↓ ↓H␈↓There␈α∞is␈α
no␈α∞standard␈α∞LISP␈α
editor␈α∞or␈α∞debugger.␈α
Therefore␈α∞the␈α∞next␈α
sections␈α∞will␈α∞contain␈α
general
␈↓ ↓H␈↓information␈α⊃rather␈α⊂than␈α⊃an␈α⊃abundance␈α⊂of␈α⊃concrete␈α⊃examples.␈α⊂The␈α⊃design␈α⊃of␈α⊂such␈α⊃devices␈α⊃is␈α⊂a
␈↓ ↓H␈↓subject␈αof␈αvery␈αpersonal␈αpreferences␈αand␈α
prejudices.␈αSome␈αcharacteristics␈αare␈αcommon␈αand␈αthose␈α
we
␈↓ ↓H␈↓will␈α
stress.␈α∞A␈α
related␈α
difficulty␈α∞is␈α
that␈α
editing␈α∞and␈α
debugging␈α
devices␈α∞are␈α
best␈α
done␈α∞as␈α
interactive
␈↓ ↓H␈↓display␈αprograms,␈αrather␈αthan␈αas␈αkey-punch␈αor␈αteletype␈αprograms␈↓π 217␈↓.␈αInteractive␈αprogramming␈αis␈αa
␈↓ ↓H␈↓very␈α
visual␈αand␈α
dynamic␈α
enterprise;␈αteletype-oriented␈α
interaction␈α
is␈αnot␈α
sufficient␈α
since␈αit␈α
results␈αin␈α
a
␈↓ ↓H␈↓presentation more like a comic strip than a movie.
␈↓ ↓H␈↓␈↓ ¬V␈↓↓6.22 LISP Editors␈↓
␈↓ ↓H␈↓A␈αLISP␈αeditor␈αis␈αjust␈αanother␈αLISP␈αprogram;␈αit␈αoperates␈αon␈αa␈αdata␈αstructure.␈αIn␈αthis␈αcase␈αthe␈αdata
␈↓ ↓H␈↓structure␈α∞represents␈α
a␈α∞program.␈α∞A␈α
simple␈α∞editor␈α
could␈α∞be␈α∞constructed␈α
along␈α∞the␈α
lines␈α∞of␈α∞the␈α
␈↓αsubst␈↓
␈↓ ↓H␈↓function:
␈↓ ↓H␈↓αsubst␈↓λ'␈↓α <= λ[[x;y;z]␈↓ βH[atom[z] → [equal[y;z] → x; ␈↓
t␈↓α → z];
␈↓ ↓H␈↓α␈↓ βH ␈↓
t␈↓α → cons[␈↓ ∧Hsubst␈↓λ'␈↓α[x;y;car[z]];
␈↓ ↓H␈↓α␈↓ βH␈↓ ∧Hsubst␈↓λ'␈↓α[x;y;cdr[z]]]]]
␈↓ ↓H␈↓That␈α∞is,␈α
we␈α∞would␈α
let␈α∞␈↓αz␈↓␈α∞be␈α
the␈α∞program;␈α
␈↓αy␈↓,␈α∞the␈α
piece␈α∞of␈α∞text␈α
to␈α∞be␈α
replaced;␈α∞and␈α
␈↓αx␈↓,␈α∞the␈α∞new␈α
text.
␈↓ ↓H␈↓Such global editing ␈↓↓is␈↓ useful, but control of text editing is necessary.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 217␈↓ That is one of the author's preferences and prejudices.
␈↓ ↓H␈↓␈↓↓6.22␈↓ KLISP Editors 343␈↓
␈↓ ↓H␈↓A␈α∞typical␈α∞editor␈α∂will␈α∞take␈α∞an␈α∂expression␈α∞as␈α∞input␈α∂and␈α∞will␈α∞then␈α∂enter␈α∞a␈α∞"listen-loop",␈α∂waiting␈α∞for
␈↓ ↓H␈↓commands␈α
from␈αthe␈α
user.␈α
The␈αinput␈α
expression␈αmay␈α
either␈α
be␈αa␈α
list␈αrepresenting␈α
a␈α
constant␈αdata
␈↓ ↓H␈↓structure,␈α
or␈α∞a␈α
list␈α
representing␈α∞a␈α
(constant)␈α
function.␈α∞ There␈α
are␈α
commands␈α∞for␈α
the␈α
selection␈α∞of␈α
a
␈↓ ↓H␈↓subexpression␈αof␈αthe␈αinput␈αexpression;␈αand␈αthere␈αare␈αcommands␈αfor␈αthe␈αreplacement␈αof␈αexpressions
␈↓ ↓H␈↓with other expressions.
␈↓ ↓H␈↓The␈α
mechanics␈α
of␈α
presenting␈α
list␈α∞structure␈α
to␈α
the␈α
user␈α
are␈α∞interesting.␈α
Since␈α
a␈α
list␈α
may␈α∞be␈α
deeply
␈↓ ↓H␈↓nested,␈α∂we␈α∞need␈α∂a␈α∞convenient␈α∂way␈α∞of␈α∂designating␈α∞subexpressions.␈α∂On␈α∞a␈α∂display␈α∞device␈α∂we␈α∞might
␈↓ ↓H␈↓display␈α∞the␈α∞selected␈α∞expression␈α∞more␈α∞brightly␈α∞than␈α∞the␈α∞containing␈α∞expression.␈α∞That␈α∞is␈α∞useful,␈α∞but
␈↓ ↓H␈↓more␈α?␈αβstructured␈α?␈αβrepresentations␈α?␈αβof␈α?␈αβtext␈α?␈αβare␈α?␈αβrequired.␈α?␈α∧ Typically,␈α?␈αβa
␈↓ ↓H␈↓"pretty-printed" (Section 9.2 or page 254)␈α∃version␈α∃of␈α⊗the␈α∃text␈α∃is␈α∃presented.␈α⊗ If␈α∃the␈α∃text␈α⊗is␈α∃too
␈↓ ↓H␈↓extensive to fit on the display face, then abbreviational devices are available.
␈↓ ↓H␈↓If␈α∪the␈α∀text␈α∪is␈α∀deeply␈α∪nested␈α∪it␈α∀is␈α∪often␈α∀difficult␈α∪to␈α∪perceive␈α∀the␈α∪top␈α∀level␈α∪structure␈α∀even␈α∪in
␈↓ ↓H␈↓pretty-printed form. Consider the S-expr representation of the definition of ␈↓αmember␈↓:
␈↓ ↓H␈↓α(MEMBER
␈↓ ↓H␈↓α (LAMBDA (X L)
␈↓ ↓H␈↓α (COND␈↓ αX((NULL L) NIL)
␈↓ ↓H␈↓α␈↓ αX((EQ X (FIRST L)) T)
␈↓ ↓H␈↓α␈↓ αX(T (MEMBER X (REST L))))))
␈↓ ↓H␈↓In this case the structure of the ␈↓αCOND␈↓ is clear; but it is clearer if we express it as:
␈↓ ↓H␈↓α␈↓ αX(LAMBDA (X L) (COND & & &))
␈↓ ↓H␈↓Or given a linear list:␈↓ ¬+␈↓α(␈↓εa b c d e f g h i j k l␈↓α)␈↓
␈↓ ↓H␈↓it may be more instructive to display it as:
␈↓ ↓H␈↓␈↓ ¬!␈↓α(␈↓εa b c d e f g h i ␈↓α... )␈↓ or,
␈↓ ↓H␈↓␈↓ ¬Z␈↓α( ...␈↓εd e f g h i ␈↓α... )␈↓.
␈↓ ↓H␈↓where the focus of attention is controlled by the user.
␈↓ ↓H␈↓There␈αshould␈αbe␈αcommands␈αto␈αmove␈αselected␈αsubexpressions␈αto␈αdifferent␈αlocations␈αwithin␈αthe␈αsame
␈↓ ↓H␈↓structure␈α⊂and␈α⊂move␈α⊃expressions␈α⊂to␈α⊂other␈α⊂structures.␈α⊃Since␈α⊂a␈α⊂common␈α⊂text␈α⊃error␈α⊂in␈α⊂LISP␈α⊃is␈α⊂the
␈↓ ↓H␈↓misplacing of parentheses, there are commands to move parentheses.
␈↓ ↓H␈↓There␈αare␈αat␈αleast␈αtwo␈αreasons␈αfor␈αtext␈αeditors:␈αprogrammers␈αmake␈αerrors,␈αand␈αprograms␈αwhich␈αare
␈↓ ↓H␈↓correct␈α
need␈α∞to␈α
be␈α
modified␈α∞to␈α
perform␈α∞other␈α
tasks.␈α
Particularly␈α∞in␈α
exploratory␈α∞programming,␈α
the
␈↓ ↓H␈↓"try-it-and-see"␈α∞attitude␈α∞must␈α∞be␈α∞supported.␈α∞Thus␈α∞we␈α∞demand␈α∞a␈α∞flexible␈α∞editor␈α∞which␈α∂can␈α∞"undo"
␈↓ ↓H␈↓changes␈αto␈α
functions␈αor␈α
constant␈αdata␈α
structure.␈α LISP␈α
editors␈αhave␈α
the␈αability␈α
to␈αsave␈α
the␈αcurrent
␈↓ ↓H␈↓edit structure such that an "undo" can restore to that state if needed.
␈↓ ↓H␈↓␈↓↓344 Dynamic Structure␈↓ '6.22␈↓
␈↓ ↓H␈↓Regardless␈αof␈αthe␈αidiosyncrasies␈αof␈αa␈αparticular␈αeditor␈αthe␈αcommon␈αfeature␈αis␈αthat␈αLISP␈αeditors␈αare
␈↓ ↓H␈↓structure-oriented␈α∩editors.␈α∩They␈α∩operate␈α∩on␈α∩well-formed␈α∩S-expressions,␈α∩not␈α∩text␈α∩strings␈α∪or␈α∩card
␈↓ ↓H␈↓images.␈α∞ A␈α∞program␈α∞is␈α
not␈α∞a␈α∞linear␈α∞string␈α
of␈α∞characters;␈α∞it␈α∞is␈α
a␈α∞structured␈α∞entity,␈α∞whose␈α∞parts␈α
are
␈↓ ↓H␈↓distinguishable␈α∞as␈α∞representations␈α∞of␈α∂instances␈α∞of␈α∞programming␈α∞language␈α∞constructs.␈α∂ The␈α∞editing
␈↓ ↓H␈↓process should take cognizance of that structure␈↓π 218␈↓.
␈↓ ↓H␈↓␈↓ ¬(␈↓↓6.23 Debugging in LISP␈↓
␈↓ ↓H␈↓Few␈α
areas␈α
of␈α
the␈α
Computer␈α
Science␈α
field␈α
are␈αas␈α
primitive␈α
as␈α
that␈α
of␈α
debugging.␈α
Few␈α
areas␈α
of␈αthe
␈↓ ↓H␈↓field␈α
are␈α
as␈α
important.␈α
Getting␈α
a␈α
correct␈α
program␈α
indeed␈α
is␈α
the␈α
whole␈α
point␈α
of␈α
our␈αprogramming.
␈↓ ↓H␈↓The␈α⊃power␈α⊂of␈α⊃our␈α⊂debugging␈α⊃techniques␈α⊃has␈α⊂been␈α⊃directly␈α⊂related␈α⊃to␈α⊂the␈α⊃sophistication␈α⊃of␈α⊂the
␈↓ ↓H␈↓hardware/software␈α∩interface␈α∩which␈α∩is␈α∩available.␈α∩ Not␈α∩until␈α∩the␈α∩advent␈α∩of␈α∪sophisticated␈α∩on-line
␈↓ ↓H␈↓systems has there really been any hope for practical "correct-program" construction.
␈↓ ↓H␈↓Several␈αpieces␈α
of␈αinformation␈α
are␈αrequired␈α
to␈αdo␈αinteractive␈α
debugging.␈αWe␈α
need␈αan␈α
indication␈αof
␈↓ ↓H␈↓the␈αerror␈αcondition;␈αwe␈αneed␈αthe␈αcurrent␈αstate␈αof␈αthe␈αcomputation;␈αwe␈αneed␈αto␈αhave␈αsome␈αindication
␈↓ ↓H␈↓of␈α⊃how␈α⊂the␈α⊃computation␈α⊃arrived␈α⊂at␈α⊃the␈α⊂error␈α⊃condition;␈α⊃and,␈α⊂if␈α⊃interactive␈α⊂debugging␈α⊃is␈α⊃to␈α⊂be
␈↓ ↓H␈↓meaningful,␈αwe␈αneed␈αthe␈αability␈αto␈αmodify␈αthe␈αcomputation␈αand␈αresume␈αexecution␈αin␈αthat␈αmodified
␈↓ ↓H␈↓environment.␈α This␈α
last␈αpoint␈α
is␈αquite␈α
important;␈αit␈α
has␈αimplications␈α
for␈αprogramming␈α
style.␈α First,
␈↓ ↓H␈↓we␈α␈↓↓should␈↓␈αhope␈α
to␈αmodify␈αan␈αerrant␈α
calculation␈αrather␈αthan␈αrestart␈α
the␈αentire␈αcomputation.␈αTo␈α
start
␈↓ ↓H␈↓over␈αis␈αlike␈αrepunching␈αa␈αwhole␈αcard␈αdeck␈αbecause␈αone␈αcard␈αwas␈αwrong.␈αWe␈αrepunch␈αthe␈α
offending
␈↓ ↓H␈↓cards␈αand␈αretain␈αthe␈αrest.␈αSimilarly␈αwe␈αshould␈αexplore␈αthe␈αpossibilities␈αof␈αthrowing␈αaway␈αoffending
␈↓ ↓H␈↓computations␈α∩and␈α∩retaining␈α∩the␈α∪rest.␈α∩Typically,␈α∩computation␈α∩is␈α∪not␈α∩as␈α∩local␈α∩and␈α∪exciseable␈α∩as
␈↓ ↓H␈↓removing␈α
a␈α
single␈α
card;␈α
a␈α
primary␈α
purpose␈α
of␈α∞most␈α
computation␈α
is␈α
to␈α
pass␈α
a␈α
result␈α
to␈α∞some␈α
other
␈↓ ↓H␈↓procedure.␈α However,␈αif␈α
we␈αtry␈αto␈αlocalize␈α
the␈αeffects␈αof␈αeach␈α
procedure␈αto␈αsimple␈αparameter␈α
passing
␈↓ ↓H␈↓and␈α⊂value␈α⊃returning␈α⊂then␈α⊃we␈α⊂have␈α⊃a␈α⊂better␈α⊃chance␈α⊂of␈α⊃discovering␈α⊂a␈α⊃point␈α⊂in␈α⊃the␈α⊂computation
␈↓ ↓H␈↓history␈α∩which␈α∩is␈α∩prior␈α⊃to␈α∩the␈α∩error;␈α∩return␈α⊃the␈α∩control␈α∩stack␈α∩to␈α⊃that␈α∩point;␈α∩modify␈α∩the␈α⊃erring
␈↓ ↓H␈↓procedure␈αand␈αrestart␈αthe␈α
computation.␈αThis␈αimplies␈αthat␈α
procedures␈αshould␈αminimize␈αtheir␈α
use␈αof
␈↓ ↓H␈↓side-effects;␈α⊂for␈α⊂it␈α⊂is␈α⊂side-effects␈α⊂which␈α⊂spoil␈α∂the␈α⊂nice␈α⊂applicative␈α⊂behavior␈α⊂and␈α⊂will␈α⊂require␈α∂the
␈↓ ↓H␈↓programmer␈α
to␈α
make␈α
explicit␈α
modifications␈αin␈α
the␈α
computational␈α
environment␈α
before␈αa␈α
computation
␈↓ ↓H␈↓can␈α
be␈α
restarted.␈α
Such␈α
a␈α
programming␈α
style␈α
is␈α
called␈α
␈↓↓modular␈α
programming␈↓,␈α
meaning␈α
that␈α
each
␈↓ ↓H␈↓procedure␈α
is␈α
a␈α
module,␈α
or␈α
black␈α
box,␈α
dependent␈α
on␈α
other␈α
procedures␈α
only␈α
by␈α
way␈α
of␈α
well-defined
␈↓ ↓H␈↓input␈α
and␈αoutput␈α
considerations.␈α It␈α
is␈α
this␈αstyle␈α
of␈αmodular␈α
programming␈αwhich␈α
will␈α
enhance␈αthe
␈↓ ↓H␈↓use of interactive debugging tools.
␈↓ ↓H␈↓This␈α∀section␈α∀will␈α∀deal␈α∀only␈α∀with␈α∀the␈α∀primitive␈α∀mechanisms␈α∀which␈α∀underlie␈α∀LISP␈α∪debugging
␈↓ ↓H␈↓techniques.␈α∞The␈α∂discussions␈α∞of␈α∂more␈α∞complex␈α∂tools␈α∞which␈α∂are␈α∞available␈α∂or␈α∞are␈α∂comtemplated␈α∞are
␈↓ ↓H␈↓well-documented in other sources; [Int 75], [Moo 74].
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 218␈↓␈α
A␈αcase␈α
can␈α
be␈αmade␈α
for␈αbelieving␈α
that␈α
the␈αprogram␈α
␈↓↓construction␈↓␈α
process␈αshould␈α
also␈αbe␈α
driven
␈↓ ↓H␈↓by that structure [Han 71].
␈↓ ↓H␈↓␈↓↓6.23␈↓ λoDebugging in LISP 345␈↓
␈↓ ↓H␈↓Crucial␈α∞pieces␈α
of␈α∞information␈α
about␈α∞the␈α
behavior␈α∞of␈α
the␈α∞program␈α
are:␈α∞which␈α
functions␈α∞are␈α
being
␈↓ ↓H␈↓entered,␈αwhat␈αare␈αthe␈αactual␈αparameters,␈αand␈αwhat␈αare␈αthe␈αvalues␈αbeing␈αreturned.␈α Assume␈αthat␈αwe
␈↓ ↓H␈↓wish␈α⊂to␈α⊂monitor␈α⊂the␈α⊂behavior␈α⊂of␈α⊂the␈α⊂function,␈α⊂␈↓αfoo␈↓.␈α⊂We␈α⊂will␈α⊂place␈α⊂the␈α⊂real␈α⊂definition␈α⊂of␈α⊂␈↓αfoo␈↓␈α⊂on
␈↓ ↓H␈↓another symbol table entry (using ␈↓αgensym[]␈↓) and redefine ␈↓αfoo␈↓ such that, when it is called, it will:
␈↓ ↓H␈↓␈↓ αh␈↓↓1.␈↓ print the values of the current actual parameters.
␈↓ ↓H␈↓␈↓ αh␈↓↓2.␈↓ use ␈↓αapply␈↓ to call the real defintion of ␈↓αfoo␈↓ with the current parameters.
␈↓ ↓H␈↓␈↓ αh␈↓↓3.␈↓ print the value of the call on ␈↓αfoo␈↓.
␈↓ ↓H␈↓␈↓ αh␈↓↓4.␈↓ return control and the value to the calling program.
␈↓ ↓H␈↓This␈αtechnique␈α
is␈αcalled␈αtracing,␈α
and␈αthe␈αdescription␈α
we␈αhave␈α
given␈αis␈αone␈α
suitable␈αto␈αa␈α
teletype-like
␈↓ ↓H␈↓device.␈α∂Given␈α∞an␈α∂interactive␈α∞display␈α∂and␈α∞a␈α∂well-defined␈α∞"LISP␈α∂machine"␈α∞description␈α∂like␈α∂that␈α∞in
␈↓ ↓H␈↓␈↓αpeval␈↓ (Section 4.8), a much more satisfactory trace can be given.
␈↓ ↓H␈↓Since␈α∞␈↓αfoo␈↓␈α∞may␈α∞be␈α∞recursive␈α∞we␈α∞should␈α∞also␈α∞give␈α∞some␈α∞indication␈α∞of␈α∞the␈α∞depth␈α∞of␈α∞recursion␈α
being
␈↓ ↓H␈↓executed.␈α Now␈αevery␈αcall␈α
on␈α␈↓αfoo␈↓␈αwill␈αgive␈α
us␈αthe␈αpertinent␈αstatistics.␈α
Interpreted␈αcalls␈αon␈α␈↓αfoo␈↓␈αwill␈α
go
␈↓ ↓H␈↓through␈α
␈↓αeval␈↓,␈αand␈α
if␈α
␈↓α(CALL␈α...␈α
FOO)␈↓␈α
is␈αbeing␈α
used␈α
in␈αthe␈α
compiled␈α
code␈αthe␈α
submonitor␈α
can␈αpass
␈↓ ↓H␈↓control␈α∞to␈α∂the␈α∞tracing␈α∂mechanism;␈α∞but␈α∞if␈α∂the␈α∞call␈α∂is␈α∞a␈α∞␈↓αPUSHJ␈↓,␈α∂the␈α∞control␈α∂passes␈α∞directly␈α∂to␈α∞the
␈↓ ↓H␈↓machine language code and we will not intercept the call.
␈↓ ↓H␈↓On␈αmost␈α
implementations␈αof␈αLISP␈α
the␈α␈↓αCALL␈↓␈αmay␈α
be␈αreplaced␈αby␈α
a␈α␈↓αPUSHJ␈↓.␈αThis␈α
is␈αdone␈αto␈α
speed
␈↓ ↓H␈↓execution,␈αsince␈α
a␈α␈↓αPUSHJ␈↓␈αexecuted␈α
at␈αmachine␈α
speed,␈αtransfering␈αto␈α
known␈αlocation;␈α
whereas␈αthe
␈↓ ↓H␈↓␈↓αCALL␈↓␈αis␈αpassed␈αto␈α␈↓αdecode␈↓ (page 293)␈αand␈αthe␈αfunction␈αdefinition␈αis␈αlooked␈αup.␈αTypically␈αthere␈α
is␈αa
␈↓ ↓H␈↓programmer-controlled␈α⊂mechanism␈α⊂for␈α⊂replacing␈α⊂␈↓αCALL␈↓s␈α∂with␈α⊂␈↓αPUSHJ␈↓s␈↓π 219␈↓.␈α⊂ After␈α⊂a␈α⊂program␈α∂is
␈↓ ↓H␈↓debugged,␈αthe␈α
programmer␈αmay␈α
replace␈αthe␈α␈↓αCALL␈↓␈α
with␈αthe␈α
␈↓αPUSHJ␈↓␈αand␈α
the␈αprograms␈αwill␈α
execute
␈↓ ↓H␈↓faster.␈α
On␈αsome␈α
implementations␈αthis␈α
action␈αis␈α
even␈α
reversible ([Ste pc]);␈αa␈α
table␈αis␈α
kept,␈αrelating␈α
the
␈↓ ↓H␈↓␈↓αCALL␈↓s to the ␈↓αPUSHJ␈↓s; when tracing is desired, the ␈↓αCALL␈↓ version is made available␈↓π 220␈↓.
␈↓ ↓H␈↓A␈αvariant␈αof␈αthis␈αtracing␈αscheme␈αcan␈αbe␈αused␈αto␈αmonitor␈α␈↓αSET␈↓s␈αand␈α␈↓αSETQ␈↓s.␈α We␈αcan␈αmodify␈αtheir
␈↓ ↓H␈↓definitions␈α⊂to␈α∂print␈α⊂the␈α⊂name␈α∂of␈α⊂the␈α∂variable␈α⊂and␈α⊂the␈α∂new␈α⊂value,␈α∂perform␈α⊂the␈α⊂assignment,␈α∂and
␈↓ ↓H␈↓return.␈α∩ This␈α∪technique␈α∩can␈α∩be␈α∪lost␈α∩in␈α∩some␈α∪compiled␈α∩code.␈α∩If␈α∪we␈α∩compile␈α∩local␈α∪variables␈α∩as
␈↓ ↓H␈↓references␈αinto␈αthe␈αvalue␈α
stack,␈αwe␈αhave␈αlost␈α
both␈αthe␈αnames␈αand␈α
the␈αability␈αto␈αtrace␈αtheir␈α
behavior.
␈↓ ↓H␈↓Variable␈α
references␈αwhich␈α
use␈α␈↓αPUTV␈↓␈α
and␈α␈↓αGETV␈↓␈α
can␈αbe␈α
traced␈αlike␈α
␈↓αCALL␈↓.␈αIn␈α
fact,␈αon␈α
␈↓ SM␈↓,␈αwe␈α
have
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 219␈↓ As we have seen, ␈↓αCALL␈↓s to functional variables won't be replaced.
␈↓ ↓H␈↓␈↓π 220␈↓␈αActually,␈αthe␈αscheme␈αis␈αas␈αfollows:␈αinstead␈αof␈αassembling␈αthe␈α␈↓αCALL␈↓␈αinto␈αa␈αmemory␈αlocation,␈αan
␈↓ ↓H␈↓XCT␈α∞is␈α∞assembled;␈α∞the␈α
XCT␈α∞references␈α∞a␈α∞copy␈α
of␈α∞a␈α∞table␈α∞which␈α
contains␈α∞the␈α∞actual␈α∞␈↓αCALL␈↓.␈α
The
␈↓ ↓H␈↓user␈α
may␈α∞replace␈α
the␈α
␈↓αCALL␈↓s␈α∞by␈α
␈↓αPUSHJ␈↓,␈α∞but␈α
also␈α
has␈α∞the␈α
original␈α
table␈α∞available␈α
to␈α∞replace␈α
the
␈↓ ↓H␈↓modified␈α
version␈α
when␈α
tracing␈α
is␈α
desired.␈α∞This␈α
XCT␈α
trick␈α
has␈α
the␈α
additional␈α
benefit␈α∞of␈α
allowing
␈↓ ↓H␈↓several␈α
users␈α
to␈α
share␈α
a␈α
"pure"␈α
piece␈α
of␈α
program,␈α
while␈α
some␈α
people␈α
are␈α
tracing␈α
and␈α∞some␈α
people
␈↓ ↓H␈↓are not.
␈↓ ↓H␈↓␈↓↓346 Dynamic Structure␈↓ '6.23␈↓
␈↓ ↓H␈↓an␈α∂operation␈α∞analogous␈α∂to␈α∞␈↓αPUSHJ␈↓,␈α∂so␈α∞the␈α∂␈↓αCALL-PUSHJ␈↓␈α∞technique␈α∂is␈α∞open␈α∂to␈α∞us.␈α∂ ␈↓αPUTV␈↓␈α∞and
␈↓ ↓H␈↓␈↓αGETV␈↓ can be implemented as hardware ␈↓αMOVEM␈↓ and ␈↓αMOVE␈↓ instructions.
␈↓ ↓H␈↓The␈α⊃trace␈α⊃facility␈α⊃is␈α∩a␈α⊃debugging␈α⊃feature␈α⊃which␈α∩has␈α⊃been␈α⊃adapted␈α⊃from␈α∩the␈α⊃batch-processsing
␈↓ ↓H␈↓versions␈α∂of␈α⊂LISP.␈α∂There␈α⊂is␈α∂a␈α∂related,␈α⊂but␈α∂more␈α⊂interactive,␈α∂version␈α∂of␈α⊂this␈α∂technique␈α⊂called␈α∂the
␈↓ ↓H␈↓␈↓↓break␈↓␈α∂package.␈α∂ In␈α⊂this␈α∂mode␈α∂of␈α⊂tracing,␈α∂the␈α∂user␈α⊂can␈α∂specify␈α∂that␈α⊂the␈α∂program␈α∂should␈α⊂halt␈α∂on
␈↓ ↓H␈↓recognition␈αof␈α
certain␈αconditions.␈αIf␈α
that␈αhalt␈αoccurs,␈α
the␈αbreak␈α
package␈αis␈αentered␈α
and␈αthe␈αuser␈α
may
␈↓ ↓H␈↓then␈α∂type␈α∂commands␈α∂which␈α∂survey␈α∂the␈α∂state␈α∂of␈α∂the␈α∂computation.␈α∂Expressions␈α∂may␈α∂be␈α∂evaluated,
␈↓ ↓H␈↓which␈α⊂may␈α∂themselves␈α⊂enter␈α∂the␈α⊂break␈α⊂package␈α∂recursively.␈α⊂If␈α∂desired,␈α⊂the␈α∂LISP␈α⊂editor␈α⊂may␈α∂be
␈↓ ↓H␈↓called␈αeither␈αto␈αedit␈αfunction␈αdefinitions␈αor␈αto␈αedit␈αan␈αexpression␈αon␈αthe␈αactual␈αcontrol␈αstack␈αof␈αthe
␈↓ ↓H␈↓current computation.
␈↓ ↓H␈↓Since␈α∞it␈α∞is␈α∞difficult␈α∞to␈α∞predetermine␈α∞when␈α∞a␈α∞computation␈α∞may␈α∞require␈α∞debugging,␈α∞several␈α∞systems
␈↓ ↓H␈↓supply␈α∞an␈α∞interrupt␈α∞system␈α∞analogous␈α∞to␈α∂that␈α∞found␈α∞in␈α∞hardware␈α∞machines.␈α∞Striking␈α∂certain␈α∞keys
␈↓ ↓H␈↓may␈αthen␈αcause␈αinterrupts␈αto␈αthe␈αbreak␈αpackage,␈αjust␈αas␈αif␈αa␈αbreak␈αcondition␈αwere␈α
pre-programmed.
␈↓ ↓H␈↓Such␈αa␈αfeature␈αis␈αuseful␈αin␈αconjunction␈αwith␈αthe␈αtrace␈αpackage.␈αIf␈αa␈αtrace␈αindicates␈αto␈αthe␈αuser␈αthat
␈↓ ↓H␈↓the␈α
computation␈α
is␈α
not␈α
performing␈α
according␈α
to␈α
expectation␈α
then␈α
an␈α
interrupt␈α
key␈α
can␈α
be␈α
struck␈α
and
␈↓ ↓H␈↓the computation will be suspended.
␈↓ ↓H␈↓User-definable␈αinterrupt␈αsystems␈αapply␈αto␈αother␈αareas␈αof␈αcomputation␈αthan␈αthat␈αof␈αdebugging.␈αThe
␈↓ ↓H␈↓most␈α⊂well-developed␈α⊃system␈α⊂is␈α⊃that␈α⊂of␈α⊃MacLISP.␈α⊂ The␈α⊃ability␈α⊂to␈α⊃selectively␈α⊂trace␈α⊃the␈α⊂execution,
␈↓ ↓H␈↓coupled␈αwith␈α
the␈αability␈αto␈α
interrupt␈αa␈αcomputation,␈α
allows␈αthe␈αuser␈α
to␈αexamine␈αcomputations␈α
which
␈↓ ↓H␈↓are suspected of divergence.
␈↓ ↓H␈↓␈↓↓7.␈↓ π/Storage Structures and Efficiency 347␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓↓CHAPTER 7
␈↓ ↓H␈↓↓␈↓ ∧
STORAGE STRUCTURES AND EFFICIENCY␈↓
␈↓ ↓H␈↓Though␈αit␈αis␈αtrue␈αthat␈αany␈αalgorithm␈αcan␈αbe␈αcoded␈αin␈αterms␈αof␈αmanipulations␈αof␈αbinary␈αtrees,␈αthere
␈↓ ↓H␈↓are␈α∞many␈α∂instances␈α∞in␈α∞which␈α∂more␈α∞efficient␈α∞organizations␈α∂of␈α∞data␈α∞exist.␈α∂ At␈α∞the␈α∂most␈α∞elementary
␈↓ ↓H␈↓level␈α∂are␈α⊂vectors␈α∂and␈α⊂arrays.␈α∂ These␈α⊂data␈α∂structures␈α⊂could␈α∂certainly␈α⊂be␈α∂stored␈α⊂in␈α∂a␈α⊂list␈α∂structure
␈↓ ↓H␈↓format␈α∞and␈α∞individual␈α∞components␈α∞accessed␈α∞via␈α∞␈↓αcar-cdr␈↓␈α∞chains.␈α∞ However,␈α∞most␈α∞machines␈α∂have␈α∞a
␈↓ ↓H␈↓hardware␈α∃organization␈α∀which␈α∃can␈α∀be␈α∃exploited␈α∀to␈α∃increase␈α∀accessing␈α∃efficiency␈α∀over␈α∃the␈α∀list
␈↓ ↓H␈↓representation.␈α∞ Similarly,␈α∞strings␈α∞can␈α∞be␈α∞represented␈α∞as␈α∞lists␈α∞of␈α∞characters.␈α∞ The␈α∞string␈α
processing
␈↓ ↓H␈↓operations␈α
are␈α
expressible␈α
as␈α
LISP␈α
algorithms.␈α∞ But␈α
again␈α
this␈α
is␈α
usually␈α
not␈α
the␈α∞most␈α
reasonable
␈↓ ↓H␈↓representation.␈α
Even␈α
at␈α
the␈α∞level␈α
of␈α
list-structure␈α
operations,␈α
simple␈α∞binary␈α
trees␈α
might␈α
not␈α∞be␈α
the
␈↓ ↓H␈↓most␈α
expeditious␈α
representation␈α
for␈α
every␈α
problem.␈α
Also␈α
many␈α
of␈α
the␈α
algorithms␈α
we␈α
have␈α
presented
␈↓ ↓H␈↓in␈α⊃LISP␈α⊃are␈α⊃overly␈α⊃wasteful␈α⊃of␈α∩computation␈α⊃time.␈α⊃ This␈α⊃section␈α⊃will␈α⊃begin␈α⊃an␈α∩examination␈α⊃of
␈↓ ↓H␈↓alternatives to LISP organization.
␈↓ ↓H␈↓There␈α
is␈α
no␈α
best␈αdata␈α
representation,␈α
nor␈α
is␈α
there␈αa␈α
best␈α
algorithm.␈α
The␈α
chosen␈αrepresentation␈α
must
␈↓ ↓H␈↓match␈α∞the␈α∞machine␈α∞and␈α∂the␈α∞problem␈α∞domain␈α∞being␈α∞studied.␈α∂ If␈α∞the␈α∞problem␈α∞is␈α∂strictly␈α∞numerical
␈↓ ↓H␈↓then␈α
list-structure␈α
is␈α
not␈αthe␈α
answer;␈α
if␈α
simple␈α
string␈αmanipulation␈α
is␈α
sufficient␈α
then␈α
list␈αprocessing␈α
is
␈↓ ↓H␈↓too␈αgeneral.␈α
And␈αthere␈αare␈α
many␈αapplications␈α
of␈αlist␈αprocessing␈α
which␈αare␈αsufficiently␈α
well-behaved
␈↓ ↓H␈↓that␈α
complex␈α
devices␈α
like␈α
garbage␈α
collectors␈α
are␈α
unnecessary.␈α
The␈α
point␈α
is␈α
that␈α
if␈α
you␈α
have␈αseen␈α
the
␈↓ ↓H␈↓list-processing␈α∞techniques␈α
in␈α∞a␈α∞rich␈α
environment␈α∞such␈α∞as␈α
LISP␈α∞and␈α∞have␈α
seen␈α∞the␈α∞applications␈α
to
␈↓ ↓H␈↓which␈αLISP␈αmay␈αbe␈αput,␈αthen␈αyou␈αwill␈α
be␈αprepared␈αto␈αapply␈αthese␈αtechniques␈αin␈αa␈αmeaningful␈α
way.
␈↓ ↓H␈↓Many␈α∀times␈α∀an␈α∀(inefficient)␈α∀representation␈α∀in␈α∀LISP␈α∀is␈α∀all␈α∀that␈α∀is␈α∀needed.␈α∀ You␈α∀get␈α∀a␈α∀clean
␈↓ ↓H␈↓representation␈α⊂with␈α⊂comprehensible␈α∂algorithms.␈α⊂ Once␈α⊂you've␈α∂studied␈α⊂the␈α⊂algorithms,␈α∂efficiencies
␈↓ ↓H␈↓might␈α⊂come␈α⊂to␈α⊂mind.␈α⊂At␈α⊂that␈α⊂time␈α⊂either␈α⊂recode␈α⊂the␈α⊂problem␈α⊂using␈α⊂some␈α⊂of␈α⊂the␈α⊂obscene␈α∂LISP
␈↓ ↓H␈↓programming␈α
tricks␈α
or␈αdrop␈α
into␈α
machine␈α
language␈αif␈α
very␈α
fine␈α
control␈αis␈α
required.␈α
Once␈αyou␈α
have
␈↓ ↓H␈↓␈↓↓a␈↓␈α∂representation␈α∂it␈α∂is␈α∂easy␈α∂to␈α∂get␈α∂better␈α∂ones.␈α∂ For␈α∂example,␈α∂once␈α∂you␈α∂have␈α∂a␈α∂compiler␈α∂which␈α∂is
␈↓ ↓H␈↓correct␈αit␈αis␈α
easier␈αto␈αdescribe␈αa␈α
smarter␈αone.␈α This␈αsection␈α
will␈αdescribe␈αother␈α
representations␈αthan
␈↓ ↓H␈↓LISP binary trees and will show some ways of increasing the efficiency of LISP programs
␈↓ ↓H␈↓␈↓ ¬v␈↓↓7.1 Bit-tables␈↓
␈↓ ↓H␈↓In␈α
the␈α
marking␈α
phase␈α
of␈α
a␈α
garbage␈α
collector␈α∞it␈α
is␈α
necessary␈α
to␈α
record␈α
the␈α
visitation␈α
of␈α∞each␈α
word.
␈↓ ↓H␈↓Frequently␈α∂it␈α∂is␈α∂not␈α∂possible␈α∂to␈α∂place␈α∂a␈α∞mark␈α∂in␈α∂the␈α∂actual␈α∂word.␈α∂ This␈α∂might␈α∂occur␈α∂for␈α∞several
␈↓ ↓H␈↓reasons:
␈↓ ↓H␈↓␈↓↓1.␈↓ For words in FS, there is no room if each word contains exactly two addresses.
␈↓ ↓H␈↓␈↓↓348 Storage Structures and Efficiency␈↓ 77.1␈↓
␈↓ ↓H␈↓␈↓↓2.␈↓␈αThe␈αword␈αis␈αin␈αFWS␈αand␈αthe␈αmeaning␈αof␈αthe␈αinformation␈αstored␈αthere␈αwould␈αbe␈αchanged␈αif␈αwe
␈↓ ↓H␈↓␈↓ ↓xset a bit.
␈↓ ↓H␈↓␈↓↓3.␈↓ In structures, more complex than dotted pairs, there may not be room for marking bits.
␈↓ ↓H␈↓␈↓↓4.␈↓␈αIf␈αa␈αbit␈αis␈αassigned␈α
to␈αeach␈αword,␈αthen␈αthe␈αinitialize␈α
phase␈αrequires␈αthat␈αwe␈αvisit␈αeach␈αsuch␈α
word.
␈↓ ↓H␈↓␈↓ ↓xThis violates "locality of reference"␈↓π 221␈↓.
␈↓ ↓H␈↓An␈α
alternative␈α
solution␈αis␈α
to␈α
designate␈α
a␈αseparate␈α
section␈α
of␈α
memory␈αcalled␈α
a␈α
␈↓↓bit-table␈↓.␈αThe␈α
bit-table
␈↓ ↓H␈↓is␈α⊃a␈α⊂sequence␈α⊃of␈α⊂binary␈α⊃flags;␈α⊂and␈α⊃there␈α⊂is␈α⊃a␈α⊂one-to-one␈α⊃correspondence␈α⊂between␈α⊃a␈α⊂flag␈α⊃and␈α⊂a
␈↓ ↓H␈↓markable␈α
location.␈α
Whenever␈αwe␈α
wish␈α
to␈α
record␈αthe␈α
visiting␈α
of␈α
a␈αword,␈α
we␈α
set␈α
the␈αcorresponding
␈↓ ↓H␈↓flag.␈α
A␈α
bit␈αtable␈α
is␈α
represented␈αas␈α
a␈α
sequence␈αof␈α
machine␈α
locations␈αwith␈α
several␈α
flags␈αrepresented␈α
in
␈↓ ↓H␈↓each␈α
word.␈α∞There␈α
is␈α∞a␈α
simple␈α∞calculation␈α
to␈α∞relate␈α
a␈α∞bit␈α
in␈α∞a␈α
word␈α∞to␈α
its␈α∞corresponding␈α
markable
␈↓ ↓H␈↓location.␈α
It␈α
is␈α
frequently␈α
faster␈α
to␈α
initialize␈α∞a␈α
whole␈α
table␈α
rather␈α
than␈α
zero␈α
single␈α
bits␈α∞in␈α
separate
␈↓ ↓H␈↓words.
␈↓ ↓H␈↓␈↓ ¬3␈↓↓7.2 Vectors and Arrays␈↓
␈↓ ↓H␈↓␈↓↓Vectors␈↓:␈α∂Vectors␈α∂(or␈α∂one␈α∂dimensional␈α∂arrays)␈α∂are␈α∂usually␈α∂stored␈α∂sequentially␈α∂in␈α∂memory.␈α∞ Simple
␈↓ ↓H␈↓vectors␈α∂are␈α∞usually␈α∂stored␈α∞one␈α∂element␈α∞to␈α∂a␈α∞memory␈α∂location␈α∞though␈α∂this␈α∞is␈α∂not␈α∞a␈α∂necessity.␈α∞ For
␈↓ ↓H␈↓example␈αa␈αcomplex␈αvector␈αis␈α
very␈αnaturally␈αstored␈αas␈αpairs␈αof␈α
cells;␈αor␈αif␈αperhaps␈αyou␈α
would␈αallow
␈↓ ↓H␈↓vectors␈αof␈αnon-homogeneous␈αdata␈αmodes,␈αeach␈αelement␈αwould␈αhave␈αto␈αinclude␈αtype␈αinformation.␈α In
␈↓ ↓H␈↓any␈α⊂case,␈α⊂most␈α⊂languages␈α⊂make␈α⊂some␈α⊂restrictions␈α∂on␈α⊂the␈α⊂behavior␈α⊂of␈α⊂vectors␈α⊂such␈α⊂that␈α∂efficient
␈↓ ↓H␈↓accessing␈α
of␈αelements␈α
can␈αbe␈α
made.␈α
There␈αis␈α
a␈αnatural␈α
simulation␈α
of␈αa␈α
stack␈αas␈α
a␈α(sequential)␈α
vector
␈↓ ↓H␈↓with access made via a global pointer to the vector.
␈↓ ↓H␈↓␈↓↓Arrays␈↓:␈α⊂Arrays␈α⊂are␈α⊂multi-dimensional␈α⊂data␈α⊂structures.␈α⊂ Since␈α⊂most␈α⊂machine␈α⊂memories␈α⊂are␈α⊂linear
␈↓ ↓H␈↓devices␈α
we␈αmust␈α
map␈αarrays␈α
onto␈αa␈α
linear␈αrepresentation.␈α
We␈αwill␈α
restrict␈αattention␈α
to␈αthe␈α
case␈αof
␈↓ ↓H␈↓two-dimensional␈αarrays.␈α Most␈αof␈αthe␈αdiscussion␈αgeneralizes␈αvery␈αnaturally.␈α A␈αvery␈αcommon␈αdevice
␈↓ ↓H␈↓is␈α∂to␈α∂store␈α∞the␈α∂array␈α∂by␈α∂rows;␈α∞that␈α∂is,␈α∂each␈α∂row␈α∞is␈α∂stored␈α∂sequentially,␈α∂first,␈α∞row␈α∂1;␈α∂then␈α∂row␈α∞2,...
␈↓ ↓H␈↓Given␈αthis␈αrepresentation␈αthere␈αis␈αa␈αtrivial␈αcalculation␈αto␈αfind␈αthe␈αlocation␈αof␈αan␈αarbitrary␈αelement,
␈↓ ↓H␈↓A[i;j],␈αif␈αwe␈αknow␈αthe␈αlocation␈αof␈αthe␈αfirst␈αelement,␈αA[1;1]␈αand␈αthe␈αextent␈αof␈αthe␈αdimensions␈αof␈αthe
␈↓ ↓H␈↓array. For an array A[1:M; 1:N]
␈↓ ↓H␈↓␈↓ ∧Ploc[A[i;j]] = loc [A[1;1]] + (i-1)*N + (j-1)
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 221␈↓
␈↓ ↓H␈↓Locality␈αrefers␈αto␈αthe␈αrelative␈αdistance␈αbetween␈αmemory␈αlocations␈αassigned␈αin␈αa␈αparticular␈αstructure.
␈↓ ↓H␈↓In␈αsome␈αmachine␈αorganizations,␈αmemory␈αis␈αdivided␈αinto␈α"pages"␈αof␈αa␈αrelatively␈αsmall␈αsize.␈αThere␈αis
␈↓ ↓H␈↓significant␈α∞overhead␈α∞involved␈α∞in␈α∞crossing␈α
page␈α∞boundaries.␈α∞Therefore␈α∞memory␈α∞referencing␈α
which
␈↓ ↓H␈↓entails many scattered references is said to violate "locality of reference.
␈↓ ↓H␈↓␈↓↓7.2␈↓ λvVectors and Arrays 349␈↓
␈↓ ↓H␈↓In␈α
languages␈α∞like␈α
Fortran␈α
which␈α∞require␈α
that␈α∞the␈α
size␈α
of␈α∞the␈α
array␈α
be␈α∞known␈α
at␈α∞compile-time␈α
the
␈↓ ↓H␈↓compiler␈α∂can␈α∂generate␈α∂the␈α∂accessing␈α∂code␈α∂without␈α∂problem.␈α∂ Languages,␈α∂like␈α∂Algol␈α∂60,␈α∂and␈α∂some
␈↓ ↓H␈↓versions␈αof␈αLISP␈αwhich␈αallow␈αthe␈αsize␈αof␈αan␈αarray␈αto␈αbe␈αdetermined␈αat␈αruntime␈αrequire␈αa␈αbit␈αmore
␈↓ ↓H␈↓care.␈α Algol␈α60,␈αfor␈αexample␈αrequires␈αthat␈αyou␈αdeclare␈αthe␈αtype␈α(real,␈αboolean,␈αetc.)␈αof␈αthe␈αarray␈αand
␈↓ ↓H␈↓specify␈αthe␈αnumber␈αof␈αdimensions␈αin␈αthe␈αarray,␈αbut␈αyou␈αcan␈αpostpone␈αuntil␈αruntime␈αthe␈αdesignation
␈↓ ↓H␈↓of␈α∂the␈α∂size␈α∂of␈α∞each␈α∂dimension.␈α∂ To␈α∂handle␈α∞this␈α∂complexity␈α∂a␈α∂dope␈α∞vector␈α∂is␈α∂introduced.␈α∂A␈α∞␈↓↓dope
␈↓ ↓H␈↓↓vector␈↓␈α⊃is␈α⊃typically␈α⊃a␈α⊂header␈α⊃or␈α⊃descriptor␈α⊃associated␈α⊃with␈α⊂the␈α⊃area␈α⊃containing␈α⊃the␈α⊃actual␈α⊂array
␈↓ ↓H␈↓elements.␈α
The␈α
information␈α
in␈α
the␈α
dope␈α
vector␈α
tells␈α
the␈α
functions␈α
which␈α
access␈α
the␈α
array,␈α
how␈α
to␈α
treat
␈↓ ↓H␈↓the data. Type and dimensionality are typical entries in dope vectors.
␈↓ ↓H␈↓The␈αcompiler␈αcan␈αdetermine␈αthe␈αsize␈αof␈αthe␈α
dope␈αvector,␈αbut␈αnot␈αthe␈αcontents.␈α The␈αdope␈α
vector␈αis
␈↓ ↓H␈↓filled␈α
in␈α
when␈αthe␈α
array␈α
declaration␈α
is␈αexecuted␈α
and␈α
contains␈α
information␈αabout␈α
the␈α
actual␈αextent␈α
of
␈↓ ↓H␈↓the␈αarray␈αbounds.␈α Since␈αthe␈αsize␈αof␈αthe␈αarray␈αis␈αnot␈αknown,␈αthe␈αcompiler␈αcannot␈αallocate␈αspace␈αfor
␈↓ ↓H␈↓the␈α
array␈α
elements.␈α
The␈α
allocation␈α
must␈α
also␈α
be␈α
done␈α
at␈α
runtime.␈α
When␈α
the␈α
array␈α
declaration␈α
is
␈↓ ↓H␈↓executed␈αwe␈αmust␈αknow␈αall␈αthe␈αinformation␈αabout␈αthe␈αarray.␈α At␈αthat␈αtime␈αwe␈αallocate␈αspace␈αon␈αthe
␈↓ ↓H␈↓stack␈α
and␈α
complete␈α
the␈α∞dope␈α
vector.␈α
Subsequent␈α
references␈α
to␈α∞array␈α
elements␈α
use␈α
the␈α∞dope␈α
vector.
␈↓ ↓H␈↓When we leave the block which caused allocation of the array, the stack space is reclaimed.
␈↓ ↓H␈↓Assume␈α∂that␈α⊂the␈α∂array␈α⊂elements␈α∂are␈α⊂stored␈α∂by␈α∂rows.␈α⊂ Look␈α∂at␈α⊂the␈α∂calculation␈α⊂of␈α∂the␈α⊂location␈α∂of
␈↓ ↓H␈↓element,␈αA[i;j].␈α For␈α
specific␈αexecution␈αof␈αan␈α
array␈αdeclaration␈αmuch␈α
of␈αthis␈αinformation␈αis␈α
constant;
␈↓ ↓H␈↓the␈α∞location␈α∞of␈α∞the␈α∞array␈α∞elements,␈α∞in␈α∞particular,␈α
A[1;1]␈α∞and␈α∞the␈α∞number␈α∞of␈α∞columns,␈α∞N,␈α∞is␈α
fixed.
␈↓ ↓H␈↓Thus we rewrite the calculation as:
␈↓ ↓H␈↓␈↓ αXconstant part␈↓ ε8variable part
␈↓ ↓H␈↓␈↓ αX [loc [A[1;1]]-N-1] +␈↓ ε8 (i*N+j)
␈↓ ↓H␈↓The␈α
constant␈α
part␈α
is␈α
stored␈α
in␈α
the␈α
dope␈α
vector.␈α
When␈α
we␈α
wish␈α
to␈α
reference␈α
an␈α
element␈α
A[i;j]␈αwe
␈↓ ↓H␈↓need only compute the variable part and add it to the constant part.
␈↓ ↓H␈↓The dope vector for A [1:M; 1:N] perhaps might contain
␈↓"␈↓ ↓H␈↓
⊂ααααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
~ 2 ~
␈↓"␈↓ ↓H␈↓
εααααααπααααααααλ
␈↓"␈↓ ↓H␈↓
~ 1 ~ M ~
␈↓"␈↓ ↓H␈↓
εααααααβααααααααλ
␈↓"␈↓ ↓H␈↓
~ 1 ~ N ~
␈↓"␈↓ ↓H␈↓
εαααααα∀ααααααααλ
␈↓"␈↓ ↓H␈↓
~ constant part ~
␈↓"␈↓ ↓H␈↓
εαααααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ . . . ~
␈↓"␈↓ ↓H␈↓
array elements
␈↓"␈↓ ↓H␈↓
~ . . . ~
␈↓"␈↓ ↓H␈↓
%ααααααααααααααα$
␈↓ ↓H␈↓There␈α→is␈α→another␈α→scheme␈α→for␈α→storing␈α~arrays␈α→which␈α→is␈α→used␈α→in␈α→some␈α→of␈α~the␈α→Burroughs
␈↓ ↓H␈↓machines ([Org 71], [Dor 76]).␈αEach␈αrow␈αis␈αstored␈αsequentially␈αand␈αaccess␈αto␈αseparate␈αrows␈αis␈αmade
␈↓ ↓H␈↓through␈α
a␈α∞device␈α
called␈α
a␈α∞␈↓↓mother-vector␈↓.␈α
The␈α∞mother␈α
vector␈α
is␈α∞a␈α
vector␈α
of␈α∞pointers␈α
to␈α∞the␈α
rows.
␈↓ ↓H␈↓Thus:
␈↓ ↓H␈↓␈↓↓350 Storage Structures and Efficiency␈↓ 57.2␈↓
␈↓ ↓H␈↓
⊂ααααααα⊃ ⊂αααααααααααααααααα␈↓ πXαααα⊃
␈↓"␈↓ ↓H␈↓
~ #ααβααα→~ A␈↓β11␈↓
A␈↓β12␈↓
...␈↓ πXA␈↓β1N␈↓
␈↓ λ_~
␈↓"␈↓ ↓H␈↓
εαααααααλ %αααααααααααααααααα␈↓ πXαααα$
␈↓"␈↓ ↓H␈↓
~ #ααβαα→ ..
␈↓"␈↓ ↓H␈↓
εαααααααλ
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
εαααααααλ ⊂αααααααααααααααααα␈↓ πXαααα⊃
␈↓"␈↓ ↓H␈↓
~ #ααβααα→~ A␈↓βM1␈↓
A␈↓βM2␈↓
...␈↓ πXA␈↓βMN␈↓
␈↓ λ_~
␈↓"␈↓ ↓H␈↓
%ααααααα$ %αααααααααααααααααα␈↓ πXαααα$
␈↓ ↓H␈↓Notice␈α
that␈αthe␈α
accessing␈α
computation␈αis␈α
very␈αcheap␈↓π 222␈↓.␈α
Another␈α
effect␈αis␈α
that␈α
all␈αrows␈α
need␈αnot␈α
be
␈↓ ↓H␈↓in␈α
memory␈αat␈α
once.␈α On␈α
a␈αpaging␈α
or␈α
segmenting␈αmachine␈α
this␈αarray␈α
organization␈αcan␈α
be␈αhelpful.␈α
If
␈↓ ↓H␈↓an␈α∞access␈α∞to␈α∞a␈α∞row␈α∞not␈α∞in␈α∞core␈α∞is␈α∞made,␈α∞a␈α∞`page␈α∞fault'␈α∞is␈α∞raised;␈α∞the␈α∞monitor␈α∞brings␈α∞the␈α∞row␈α∞into
␈↓ ↓H␈↓memory␈α→and␈α→the␈α→computation␈α→continues.␈α→ The␈α→mother-vector␈α→scheme␈α→generalizes␈α~nicely␈α→to
␈↓ ↓H␈↓multidimensionality and can be used in conjunction with a dope vector.
␈↓ ↓H␈↓A typical implementation of an array facility in LISP would include a declaration:
␈↓ ↓H␈↓␈↓αarray␈↓␈↓α[␈↓<identifier>;<type>;<bounds>;␈α∂...␈α∂;<bounds>],␈α∂where␈α∂the␈α∂identifier␈α∂names␈α∂the␈α∂array;␈α∂the␈α∂type
␈↓ ↓H␈↓␈↓ αhcould␈α
be␈αnumeric␈α
or␈αS-expr;␈α
and␈αfinally␈α
a␈αdeclaration␈α
of␈αupper␈α
and␈αlower␈α
bounds␈αfor
␈↓ ↓H␈↓␈↓ αheach␈αdimension␈αwould␈α
be␈αneeded.␈α ␈↓αarray␈↓␈αis␈α
a␈αspecial␈αform␈αwhose␈α
effect␈αis␈αto␈α
make␈αthe
␈↓ ↓H␈↓␈↓ αharray name a ␈↓αSUBR␈↓, whose code is the calculation of the dope vector. Thus:
␈↓"␈↓ ↓H␈↓
⊂ααααααπαααα⊃ ⊂ααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
~ SUBR ~ #αβ→αα→~ dope vector ~
␈↓"␈↓ ↓H␈↓
%αααααα∀αααα$ ~ calculation ~
␈↓"␈↓ ↓H␈↓
εαααααααααααααλ
␈↓"␈↓ ↓H␈↓
~ array ~
␈↓"␈↓ ↓H␈↓
~ elements ~
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
%ααααααααααααα$
␈↓ ↓H␈↓If␈αwe␈αare␈αto␈αstore␈αS-exprs␈αin␈αthe␈αarray␈αthen␈αthe␈αgarbage␈αcollector␈αmust␈αbe␈αable␈αto␈αmark␈αthe␈αentries.
␈↓ ↓H␈↓This is the reason for including type information.
␈↓ ↓H␈↓When␈αan␈αarray␈αelement␈α
is␈αto␈αbe␈αreferenced,␈α
then␈αthe␈αsubscripts␈αare␈α
evaluated␈α(since␈αthe␈αarray␈α
name
␈↓ ↓H␈↓was␈α∂declared␈α∂as␈α∂a␈α∂␈↓αSUBR␈↓)␈α∂and␈α∂the␈α∂dope␈α∂vector␈α∂code␈α∂is␈α∂executed,␈α∂resulting␈α∂in␈α∂a␈α∂reference␈α∂to␈α∞the
␈↓ ↓H␈↓appropriate cell.
␈↓ ↓H␈↓We also must be able to store information in the array.
␈↓ ↓H␈↓␈↓αstore[␈↓<name>[<subscr>;␈α∞...␈α∞;<subscr>];<value>]␈α∞:␈α∞␈↓αstore␈↓␈α∞is␈α∂a␈α∞special␈α∞form␈α∞whose␈α∞effect␈α∞is␈α∞to␈α∂store␈α∞the
␈↓ ↓H␈↓␈↓ αhvalue of <value> in the designated array element.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 222␈↓␈αHowever␈α
access␈αby␈αarray␈α
columns␈αcan␈α
be␈αexpensive.␈αIf␈α
each␈αrow␈α
is␈αon␈αa␈α
separate␈αpage␈α
in␈αthe
␈↓ ↓H␈↓machine, the access overhead can be substantial.
␈↓ ↓H␈↓␈↓↓7.2␈↓ λvVectors and Arrays 351␈↓
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓Implement␈α∃a␈α∃stack␈α∃in␈α∃LISP␈α∃first␈α∃using␈α∃lists␈α∃or␈α∃dotted␈α∃pairs,␈α∃then␈α∃using␈α∃an␈α∃array.␈α∃Include
␈↓ ↓H␈↓inplementations of the stack operations.
␈↓ ↓H␈↓␈↓ ¬∞␈↓↓7.3 Strings and Linear LISP␈↓
␈↓ ↓H␈↓On␈α
page 248␈α
we␈α
discussed␈α
one␈α
representation␈α
for␈α
LISP␈α
print␈α
names:␈α
a␈α
linked␈α
list␈α
of␈α
full␈αwords,␈α
each
␈↓ ↓H␈↓containing␈α∞part␈α∞of␈α∞the␈α∞external␈α
name␈α∞for␈α∞the␈α∞atom.␈α∞Print␈α∞names␈α
are␈α∞a␈α∞special␈α∞instance␈α∞of␈α∞a␈α
data
␈↓ ↓H␈↓structure␈αnamed␈αstrings,␈αand␈αour␈αuse␈αso␈αfar␈αin␈αLISP␈αof␈αstrings␈αhas␈αbeen␈αrestricted␈αto␈αmanipulating
␈↓ ↓H␈↓string␈α∞constants.␈α
In␈α∞this␈α∞section␈α
we␈α∞will␈α
discuss␈α∞alternative␈α∞representations␈α
for␈α∞strings,␈α∞and␈α
discuss
␈↓ ↓H␈↓components␈αof␈αa␈αstring-manipulating␈αlanguage.␈αThe␈αorganization␈αand␈αimplementation␈αof␈α
a␈αgeneral
␈↓ ↓H␈↓string␈α
processor␈α
directly␈α
parallels␈αLISP.␈α
In␈α
fact␈α
a␈αsubset␈α
of␈α
LISP,␈α
linear␈αLISP,␈α
is␈α
a␈α
nice␈αnotation␈α
for
␈↓ ↓H␈↓string algorithms.
␈↓ ↓H␈↓A␈αstring␈αis␈αa␈αsequence␈αof␈αcharacters.␈α A␈αlanguage␈αfor␈αstring␈αprocessing␈αshould␈αallow␈αthe␈αcreation␈αof
␈↓ ↓H␈↓strings␈α∩of␈α⊃arbitrary␈α∩length␈α∩at␈α⊃runtime;␈α∩it␈α⊃should␈α∩allow␈α∩the␈α⊃generation␈α∩of␈α⊃new␈α∩strings␈α∩and␈α⊃the
␈↓ ↓H␈↓decomposition␈α
of␈αexisting␈α
strings.␈α If␈α
strings␈α
of␈αarbitrary␈α
length␈αare␈α
to␈αbe␈α
created,␈α
an␈αorganization
␈↓ ↓H␈↓similar␈α
to␈αFS␈α
in␈αLISP␈α
can␈αbe␈α
used␈αwith,␈α
perhaps,␈αa␈α
string␈αgarbage␈α
collector.␈α We␈α
will␈α
assume␈αthis
␈↓ ↓H␈↓most␈αgeneral␈α
case.␈α The␈α
machine␈αmemory␈α
will␈αcontain␈α
at␈αleast␈α
a␈αstring␈α
space,␈αan␈α
evaluator,␈αa␈α
symbol
␈↓ ↓H␈↓table, and a garbage collector.
␈↓ ↓H␈↓String␈αspace␈α
is␈αa␈α
linear␈αsequence␈α
of␈αcells,␈α
each␈αof␈α
which␈αcan␈α
contain␈αexactly␈α
one␈αcharacter.␈α A␈α
string
␈↓ ↓H␈↓will␈αbe␈αrepresented␈αas␈αa␈αsequence␈αof␈α
contiguous␈αcharacter␈αcells.␈α A␈αstring␈αvariable␈αwill␈αbe␈α
an␈αentry
␈↓ ↓H␈↓in␈αthe␈αsymbol␈αtable;␈αthe␈αcurrent␈αvalue␈αof␈αthe␈αvariable␈αwill␈αbe␈αrepresented␈αas␈αa␈αpair:␈αcharacter␈αcount
␈↓ ↓H␈↓and a pointer to the beginning of the character sequence.
␈↓ ↓H␈↓Thus:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
~ 3 ~ # ~
␈↓"␈↓ ↓H␈↓
%ααα∀αβα$
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
%α→ααααααααα→ααα⊃
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
. . .ααααπαααπαααπαααπαααπαααπααα . . .
␈↓"␈↓ ↓H␈↓
A B B 1 D . . . string space
␈↓"␈↓ ↓H␈↓
. . .αααα∀ααα∀ααα∀ααα∀ααα∀ααα∀ααα . . .
␈↓ ↓H␈↓encodes the string ␈↓αABB␈↓.
␈↓ ↓H␈↓We␈α
must␈α
make␈α
some␈α∞decisions␈α
about␈α
how␈α
we␈α∞manipulate␈α
strings:␈α
when␈α
we␈α∞perform␈α
␈↓αx␈α
←␈α
y␈↓,␈α∞do␈α
we
␈↓ ↓H␈↓copy␈α
the␈α
symbol␈α∞table␈α
pair␈α
of␈α∞␈↓αy␈↓␈α
into␈α
that␈α
of␈α∞␈↓αx␈↓,␈α
or␈α
do␈α∞we␈α
make␈α
a␈α
new␈α∞string␈α
isomorphic␈α
to␈α∞␈↓αy␈↓␈α
and
␈↓ ↓H␈↓point␈α␈↓αx␈↓␈αat␈αit.␈α It␈αmakes␈αa␈αdifference.␈α We␈αwill␈αchoose␈αthe␈αformer,␈αcopying␈αonly␈αthe␈α`descriptor',␈αthat
␈↓ ↓H␈↓␈↓↓352 Storage Structures and Efficiency␈↓ 57.3␈↓
␈↓ ↓H␈↓is,␈α∪we␈α∩will␈α∪share␈α∪strings␈α∩(and␈α∪substrings)␈α∩wherever␈α∪possible.␈α∪This␈α∩decision␈α∪makes␈α∪the␈α∩storage
␈↓ ↓H␈↓requirements␈α∞less␈α∞expensive,␈α
but␈α∞will␈α∞make␈α∞our␈α
life␈α∞more␈α∞difficult␈α
when␈α∞we␈α∞worry␈α∞about␈α
garbage
␈↓ ↓H␈↓collection. There are three primitive functions: ␈↓αfirst␈↓, ␈↓αrest␈↓, ␈↓αconcat␈↓ (read: ␈↓αcar␈↓, ␈↓αcdr␈↓, ␈↓αcons␈↓).
␈↓ ↓H␈↓␈↓αfirst[x]␈↓␈α⊃is␈α⊃the␈α⊂first␈α⊃character␈α⊃of␈α⊂the␈α⊃string␈α⊃represented␈α⊂by␈α⊃␈↓αx␈↓.␈α⊃ ␈↓αfirst␈↓␈α⊂is␈α⊃undefined␈α⊃for␈α⊃the␈α⊂empty
␈↓ ↓H␈↓␈↓ α(string, ␈↓εe␈↓. For example:
␈↓ ↓H␈↓␈↓ ¬→␈↓αfirst[ABC]␈↓ is ␈↓αA; first[␈↓εe␈↓α]␈↓ = ␈↓λB␈↓.
␈↓ ↓H␈↓␈↓αrest[x]␈↓␈α
is␈α∞the␈α
string␈α
of␈α∞characters␈α
which␈α∞remains␈α
when␈α
the␈α∞first␈α
character␈α
of␈α∞the␈α
string␈α∞is␈α
deleted.
␈↓ ↓H␈↓␈↓ α_␈↓αrest␈↓ is also undefined for the empty string. For example:
␈↓ ↓H␈↓␈↓ ¬j␈↓αrest[ABC]␈↓ is ␈↓αBC␈↓
␈↓ ↓H␈↓␈↓αconcat[x;y]␈↓␈α∂is␈α∞a␈α∂function␈α∂of␈α∞two␈α∂arguments.␈α∞ ␈↓αx␈↓␈α∂is␈α∂a␈α∞character;␈α∂␈↓αy␈↓␈α∞is␈α∂a␈α∂string.␈α∞␈↓αconcat␈↓␈α∂forms␈α∂a␈α∞string
␈↓ ↓H␈↓␈↓ αXconsisting of the concatenation of a copy of ␈↓αx␈↓ and a copy of the string, ␈↓αy␈↓. For example:
␈↓ ↓H␈↓␈↓ ¬I␈↓αconcat[A;BC]␈↓ is ␈↓αABC␈↓.
␈↓ ↓H␈↓There are three string predicates:
␈↓ ↓H␈↓␈↓ ¬¬␈↓αchar␈↓␈↓α[x]␈↓: is ␈↓αx␈↓ a single character?
␈↓ ↓H␈↓␈↓ ¬
␈↓αnull␈↓␈↓α[x]␈↓: is ␈↓αx␈↓ the empty string?
␈↓ ↓H␈↓␈↓ ∧U␈↓αx = y␈↓: are ␈↓αx␈↓ and ␈↓αy␈↓ the same character?
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓␈↓ ελ␈↓αchar[A] ␈↓is ␈↓
t␈↓
␈↓ ↓H␈↓␈↓ ¬}␈↓αchar[AB] ␈↓is ␈↓
f␈↓
␈↓ ↓H␈↓␈↓ ¬u␈↓αAB = AB ␈↓is ␈↓λB␈↓
␈↓ ↓H␈↓The␈α⊂implementations␈α⊂of␈α⊂these␈α⊃string␈α⊂primitives␈α⊂is␈α⊂somewhat␈α⊃less␈α⊂complex␈α⊂than␈α⊂that␈α⊃for␈α⊂LISP's
␈↓ ↓H␈↓primitives.␈α ␈↓αfirst␈↓␈αgenerates␈αa␈αcharacter␈αcount␈αof␈α1␈αand␈αa␈αpointer␈αto␈αthe␈αfirst␈αcharacter␈αof␈αthe␈αparent
␈↓ ↓H␈↓string.␈α∞ ␈↓αrest␈↓␈α∞generates␈α
a␈α∞character␈α∞count␈α∞of␈α
one␈α∞less␈α∞than␈α
that␈α∞of␈α∞the␈α∞parent␈α
and␈α∞a␈α∞pointer␈α∞to␈α
the
␈↓ ↓H␈↓second character of the parent string.
␈↓ ↓H␈↓␈↓αconcat␈↓␈αis␈αa␈αbit␈αmore␈αproblematic.␈α We␈αcopy␈α␈↓αx␈↓␈αand␈αcopy␈α␈↓αy␈↓␈αso␈αthat␈α␈↓αy␈↓␈αfollows␈α␈↓αx␈↓␈αin␈αfree␈αstring␈αspace;␈αwe
␈↓ ↓H␈↓generate␈αa␈α
character␈αcount␈α
of␈αone␈α
plus␈αthe␈α
count␈αof␈α␈↓αy␈↓,␈α
and␈αgenerate␈α
a␈αpointer␈α
to␈αthe␈α
copy␈αof␈α␈↓αx␈↓.␈α
The
␈↓ ↓H␈↓copies␈α∂are␈α∂made␈α∂in␈α∂the␈α∂free␈α∂string␈α⊂space␈α∂pointed␈α∂to␈α∂by␈α∂the␈α∂␈↓↓string␈α∂space␈α∂pointer␈↓.␈α⊂ The␈α∂obvious
␈↓ ↓H␈↓question␈α⊂of␈α⊂what␈α∂to␈α⊂do␈α⊂when␈α∂string␈α⊂space␈α⊂is␈α∂exhausted␈α⊂will␈α⊂be␈α∂postponed␈α⊂for␈α⊂a␈α⊂moment.␈α∂ The
␈↓ ↓H␈↓implementations␈α∞of␈α∂the␈α∞three␈α∂predicates␈α∞are␈α∂easy:␈α∞we␈α∂will␈α∞blur␈α∂the␈α∞distinction␈α∂between␈α∞characters
␈↓ ↓H␈↓and␈α
strings␈αof␈α
length␈α
1.␈α Thus␈α
␈↓αchar␈↓␈α
need␈αonly␈α
check␈αthe␈α
character␈α
count.␈α ␈↓αnull␈↓␈α
gives␈α
␈↓
t␈↓␈αif␈α
the␈αcount␈α
is
␈↓ ↓H␈↓0.␈α⊂ What␈α⊂about = ?␈α⊂ Obviously␈α⊂characters␈α⊂are␈α⊃not␈α⊂stored␈α⊂uniquely,␈α⊂so␈α⊂we␈α⊂must␈α⊂make␈α⊃an␈α⊂actual
␈↓ ↓H␈↓character comparison.
␈↓ ↓H␈↓␈↓↓7.3␈↓ λ-Strings and Linear LISP 353␈↓
␈↓ ↓H␈↓The␈α∂implementation␈α⊂of␈α∂storage␈α∂management␈α⊂in␈α∂a␈α∂string␈α⊂processor␈α∂can␈α∂be␈α⊂more␈α∂complex␈α⊂than␈α∂a
␈↓ ↓H␈↓simple␈α
LISP␈α
implementation.␈α
We␈α
use␈α
a␈α
garbage␈α
collection␈α
scheme␈α
which␈α
in␈α
some␈α
ways,␈α
is␈α
simpler
␈↓ ↓H␈↓and␈αin␈αsome␈αways␈αmore␈αcomplicated,␈αthan␈αa␈αcollector␈αof␈αlist-structure.␈α The␈αmarking␈αphase␈αis␈αmuch
␈↓ ↓H␈↓simpler␈αsince␈αwe␈αuse␈αthe␈αdescriptor␈αin␈αthe␈αsymbol␈αtable␈αto␈αmark␈αthe␈αcharacter␈αstring.␈α Since␈αwe␈αare
␈↓ ↓H␈↓sharing␈α
substrings,␈αwe␈α
cannot␈α
stop␈αthe␈α
marking␈αsimply␈α
because␈α
we␈αhave␈α
encountered␈α
a␈αpreviously
␈↓ ↓H␈↓marked character, but at least the marking is not recursive.
␈↓ ↓H␈↓However,␈α
the␈α
collection␈α
phase␈α
needs␈α
to␈α
be␈α
more␈α
sophisticated␈α
for␈α
string␈α
processors.␈α
Since␈α
strings␈α
are
␈↓ ↓H␈↓stored␈α⊃linearly␈α⊃(or␈α∩sequentially),␈α⊃a␈α⊃fragmented␈α⊃string␈α∩space␈α⊃list␈α⊃is␈α⊃of␈α∩little␈α⊃use.␈α⊃ Thus␈α∩we␈α⊃must
␈↓ ↓H␈↓compact␈α
all␈αthe␈α
referenceable␈αstrings␈α
into␈α
one␈αend␈α
of␈αstring␈α
space,␈α
freeing␈αa␈α
linear␈αblock␈α
for␈αthe␈α
new
␈↓ ↓H␈↓free␈α∞string␈α∞space.␈α∂ Since␈α∞we␈α∞are␈α∞sharing␈α∂substrings␈α∞a␈α∞little␈α∞care␈α∂needs␈α∞to␈α∞be␈α∞exercised.␈α∂ When␈α∞we
␈↓ ↓H␈↓move␈α
a␈αstring,␈α
obviously␈α
the␈αdescriptor␈α
of␈αany␈α
variable␈α
referencing␈αany␈α
part␈αof␈α
that␈α
parent␈αstring
␈↓ ↓H␈↓must␈α
be␈αchanged␈α
to␈α
reflect␈αthe␈α
new␈α
location.␈α So␈α
before␈α
we␈αbegin␈α
the␈α
relocation␈αof␈α
strings␈α
we␈αsort
␈↓ ↓H␈↓the␈α⊂string␈α⊂descriptors␈α∂on␈α⊂the␈α⊂basis␈α∂of␈α⊂their␈α⊂pointers␈α∂into␈α⊂string␈α⊂space.␈α∂ We␈α⊂then␈α⊂recognize␈α∂each
␈↓ ↓H␈↓parent␈α∩string,␈α⊃moving␈α∩it␈α⊃down␈α∩into␈α∩freed␈α⊃locations␈α∩and␈α⊃updating␈α∩the␈α⊃address␈α∩pointers␈α∩of␈α⊃any
␈↓ ↓H␈↓substrings.␈α⊂ We␈α⊂continue␈α⊃this␈α⊂process.␈α⊂ Eventually␈α⊃all␈α⊂strings␈α⊂will␈α⊃be␈α⊂compacted␈α⊂down␈α⊃in␈α⊂string
␈↓ ↓H␈↓space.␈α
The␈α
string␈α
space␈α
pointer␈α
will␈αbe␈α
set␈α
and␈α
the␈α
computation␈α
can␈α
continue.␈α Compacting␈α
garbage
␈↓ ↓H␈↓collectors can be adapted for use in LISP or more general types of data structures.
␈↓ ↓H␈↓␈↓ ∧N␈↓↓7.4 A Compacting Collector for LISP␈↓
␈↓ ↓H␈↓We␈αcan␈αcombine␈αthe␈αsimplicity␈αof␈αthe␈αoriginal␈αmark-sweep␈αgarbage␈αcollector␈αwith␈αthe␈αsophistication
␈↓ ↓H␈↓of␈α
the␈αcollection␈α
phase␈α
of␈αstring␈α
garbage␈α
collector␈αand␈α
produce␈α
a␈αcompacting␈α
garbage␈α
collector␈αfor
␈↓ ↓H␈↓LISP.
␈↓ ↓H␈↓The␈αintention␈αis␈αto␈αmove␈αall␈αactive␈αstructures␈αto␈αcontiguous␈αlocations␈αat␈αone␈αend␈αof␈αthe␈αappropriate
␈↓ ↓H␈↓space.␈α∩There␈α∩are␈α∩several␈α∩motivations␈α∩for␈α∩compacting␈α∩storage.␈α∩First,␈α∩besides␈α∩making␈α∩the␈α⊃␈↓↓active␈↓
␈↓ ↓H␈↓storage␈αcontiguous,␈αwe␈αalso␈αmake␈αthe␈α␈↓↓free␈↓␈αlocations␈αcontiguous.␈α Thus␈αthe␈αfree␈αlists␈αcan␈αbe␈αhandled
␈↓ ↓H␈↓as arrays rather than as lists. To get the next free element, take the next element in the free array.
␈↓ ↓H␈↓The␈αsecond␈α
reason␈αfor␈α
considering␈αcompaction␈α
comes␈αup␈αin␈α
languages␈αother␈α
than␈αLISP␈↓π 223␈↓.␈α
If␈αthe
␈↓ ↓H␈↓language␈α∂allocates␈α∂storage␈α∂in␈α∞a␈α∂manner␈α∂similar␈α∂to␈α∂LISP␈α∞but␈α∂the␈α∂constructs␈α∂allow␈α∂␈↓↓different␈↓␈α∞sized
␈↓ ↓H␈↓blocks␈α∪to␈α∪be␈α∩specified␈α∪(a␈α∪string␈α∪processor␈α∩is␈α∪a␈α∪simple␈α∪example),␈α∩then␈α∪compaction␈α∪is␈α∪a␈α∩strong
␈↓ ↓H␈↓contender.␈αTo␈αsubdue␈αthe␈αfragmentation␈αof␈α
memory␈αwe␈αcould␈αconsider␈αcompacting␈αall␈αfree␈α
locations
␈↓ ↓H␈↓to␈αone␈αend␈αof␈αmemory.␈α More␈αgeneral␈αschemes␈αare␈αalso␈αviable.␈αWe␈αwill␈αtalk␈αabout␈αthese␈α
possibilities
␈↓ ↓H␈↓when we discuss dynamic allocation.
␈↓ ↓H␈↓Another␈α
reason␈α
for␈αconcern␈α
with␈α
compacting␈α
is␈αrelated␈α
to␈α
hardware.␈αIf␈α
the␈α
underlying␈α
machine␈αis
␈↓ ↓H␈↓using␈α∞a␈α∞paging␈α∞scheme,␈α∂then␈α∞we␈α∞can␈α∞try␈α∞to␈α∂minimize␈α∞page-faults␈α∞by␈α∞keeping␈α∞the␈α∂LISP␈α∞structures
␈↓ ↓H␈↓localized.␈α
In␈α
the␈α
worst␈α
case,␈α
we␈α
could␈α
have␈α
every␈α
element␈α
of␈α
a␈α
list␈α
on␈α
a␈α
separate␈α
page;␈α
this␈α
would
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 223␈↓ As we shall soon see, the rationale is applicable in LISP as well.
␈↓ ↓H␈↓␈↓↓354 Storage Structures and Efficiency␈↓ 27.4␈↓
␈↓ ↓H␈↓obviously␈αincrease␈αmachine␈αoverhead␈↓π 224␈↓.␈α However,␈αwe␈αcannot␈αrestrict␈αthe␈αoperations␈αof␈α
the␈αLISP
␈↓ ↓H␈↓programmer.␈αThe␈αunderlying␈αhardware␈α␈↓↓must␈↓␈αbe␈αinvisible␈αto␈αthe␈αuser.␈αThe␈αnext␈αbest␈αthing␈αis␈αto␈αtry
␈↓ ↓H␈↓to␈α
keep␈α
the␈α
structures␈α
as␈α
local␈α
as␈α
possible;␈α
compaction␈α
of␈α
spaces␈α
is␈α
a␈α
first␈α
attempt␈α
at␈α
this.␈α
We␈αwill
␈↓ ↓H␈↓discuss other lower-level tricks later.
␈↓ ↓H␈↓So␈αgranted␈α
that␈αcompaction␈α
is␈αa␈α
worthwhile␈αendeavor,␈α
how␈αdo␈α
we␈αproceed?␈α
Clearly␈αwe␈αcan't␈α
simply
␈↓ ↓H␈↓mark␈αall␈αthe␈αactive␈αcells␈αand␈αthen␈αmove␈αthem␈αinto␈αunmarked␈αcells␈αto␈αcompact␈αthe␈αspace.␈α We␈αmust
␈↓ ↓H␈↓also maintain the original topological relationships between the elements.
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃␈↓ ε8 ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
204 ~204~204~␈↓ is not the same as:␈↓
␈↓ ε8100 ~204~204~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$␈↓ ε8 %ααα∀ααα$
␈↓ ↓H␈↓Besides moving the cells, we must also update each reference to a moved location:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃␈↓ ε8 ⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
204 ~204~204~␈↓↓ is␈↓ the same as:␈↓
␈↓ ε8100 ~100~100~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$␈↓ ε8 %ααα∀ααα$
␈↓ ↓H␈↓To␈αhandle␈αthese␈αproblems,␈αwe␈αexpand␈αthe␈αsweep␈αphase␈αinto␈αtwo␈αphases:␈αthe␈α␈↓↓relocating␈↓␈α
phase␈αand
␈↓ ↓H␈↓the␈α
␈↓↓updating␈↓␈α
phase.␈αAs␈α
with␈α
the␈αsweep␈α
phase,␈α
there␈αare␈α
relocating␈α
and␈αupdating␈α
phases␈α
for␈α␈↓↓each␈↓
␈↓ ↓H␈↓space.
␈↓ ↓H␈↓The␈α
relocating␈αphase␈α
begins␈α
after␈αall␈α
active␈αstructure␈α
is␈α
marked.␈α Assuming␈α
we␈αare␈α
to␈α
compact␈αall
␈↓ ↓H␈↓active␈αstructure␈α␈↓↓down␈↓␈αto␈αthe␈αbottom␈αof␈αthe␈αspace.␈αFirst␈αwe␈αinitialize␈αtwo␈αpointers:␈αa␈α␈↓↓free␈↓␈αpointer␈αto
␈↓ ↓H␈↓the␈α∞lowest␈α∞cell␈α∞in␈α∞the␈α∞space;␈α∞and␈α∞an␈α∞␈↓↓active␈↓␈α
pointer␈α∞to␈α∞the␈α∞top␈α∞of␈α∞the␈α∞space.␈α∞ We␈α∞move␈α∞the␈α
active
␈↓ ↓H␈↓pointer␈αdown␈αuntil␈αwe␈αcome␈αacross␈αa␈αmarked␈αlocation;␈αwe␈αmove␈αthe␈αfree␈αpointer␈αup␈αuntil␈αwe␈αlocate
␈↓ ↓H␈↓an␈α␈↓↓unmarked␈↓␈αcell.␈α
We␈αwant␈αto␈α
move␈αthat␈αmarked␈α
cell␈αdown␈αinto␈α
the␈αfree␈αlocation;␈α
but␈αwe␈αmust␈α
also
␈↓ ↓H␈↓supply␈αenough␈α
information␈αto␈α
maintain␈αthe␈αoriginal␈α
relationships␈αin␈α
the␈αtransformed␈αstructure.␈α
The
␈↓ ↓H␈↓cell we move may reference other cells which will be moved.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 224␈↓␈α⊂Very␈α⊂little␈α⊂empirical␈α⊂work␈α⊂has␈α⊂been␈α∂done␈α⊂on␈α⊂the␈α⊂actual␈α⊂storage␈α⊂requirements␈α⊂and␈α∂running
␈↓ ↓H␈↓environment of LISP. At start is made in [Cl 76]; much more should be done.
␈↓ ↓H␈↓␈↓↓7.4␈↓ π0A Compacting Collector for LISP 355␈↓
␈↓ ↓H␈↓Here's a picture:
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
77 ~ 65~402~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
100 ~ ~ ~ ←␈↓free pointer␈↓
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
155 ~ ~ ~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
204 ~402~ 77~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
402 ~204~402~ ←␈↓active pointer␈↓
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓ ↓H␈↓Cell␈α␈↓
77␈↓␈αwas␈αactive␈αso␈αwe␈αleft␈αit␈αalone;␈αit␈αreferences␈αcell␈α␈↓
65␈↓,␈αwhich␈αhas␈αalready␈αbeen␈αvisited;␈αand␈αalso
␈↓ ↓H␈↓references␈αcell␈α␈↓
402␈↓␈αwhich␈αis␈αabout␈αto␈αmove.␈αWe␈αmove␈αthe␈αcontents␈αof␈αcell␈α␈↓
402␈↓␈αinto␈αcell␈α␈↓
100␈↓,␈αand␈αto
␈↓ ↓H␈↓let everyone know where it has gone, we leave a forwarding address of ␈↓
100␈↓ in location ␈↓
402␈↓.
␈↓ ↓H␈↓Thus:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
100 ~204~402~ ←␈↓free pointer␈↓
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
402 ~ 100~ ←␈↓active pointer␈↓
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓ ↓H␈↓The␈α
active␈αpointer,␈α
having␈αwrit,␈α
moves␈αon;␈α
it␈αskips␈α
over␈αany␈α
unmarked␈αcells,␈α
looking␈αfor␈α
the␈αnext
␈↓ ↓H␈↓marked␈α∂location.␈α∂Assume␈α∂the␈α∂next␈α∞marked␈α∂location␈α∂is␈α∂␈↓
204␈↓.␈α∂It␈α∞stops␈α∂there␈α∂and␈α∂waits␈α∂for␈α∂the␈α∞free
␈↓ ↓H␈↓pointer␈α
to␈α∞discover␈α
that␈α∞location␈α
␈↓
155␈↓␈α∞is␈α
the␈α∞next␈α
free␈α∞location.␈α
In␈α∞its␈α
search␈α∞the␈α
free␈α∞pointer␈α
will
␈↓ ↓H␈↓skip␈αover␈αany␈αmarked␈αcells.␈α The␈αsame␈αrelocation␈αoperation␈αoccurs:␈αthe␈αcontents␈αof␈α␈↓
204␈↓␈αis␈αmoved␈αto
␈↓ ↓H␈↓location␈α
␈↓
155␈↓,␈α
and␈α
the␈α
forwarding␈αaddress␈α
of␈α
␈↓
155␈↓␈α
is␈α
placed␈αin␈α
location␈α
␈↓
204␈↓.␈α
The␈α
process␈αcontinues
␈↓ ↓H␈↓until␈αthe␈αtwo␈αpointers␈αcollide.␈α Call␈αthat␈αcollision␈αpoint␈α␈↓ col␈↓.␈α When␈αthey␈αmeet,␈αall␈αlocations␈αabove
␈↓ ↓H␈↓␈↓ col␈↓␈αwill␈αeither␈αbe␈αfree␈αor␈αwill␈αcontain␈αforwarding␈αaddresses.␈αAll␈αaddresses,␈α␈↓ col␈↓␈αand␈α
below,␈αwill
␈↓ ↓H␈↓contain marked words or relocated cells. We are now ready to enter the ␈↓↓update␈↓ phase.
␈↓ ↓H␈↓␈↓↓356 Storage Structures and Efficiency␈↓ 27.4␈↓
␈↓ ↓H␈↓Here is the picture:
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
77 ~ 65~402~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
100 ~204~402~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
155 ~402~ 77~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . . ← ␈↓ col␈↓
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
204 ~ ~155~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
402 ~ ~100~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓"␈↓ ↓H␈↓
. . .
␈↓ ↓H␈↓We␈α
examine␈α
the␈α
initial␈αsegment␈α
of␈α
our␈α
space␈αfrom␈α
the␈α
bottom␈α
to␈α␈↓ col␈↓␈α
looking␈α
for␈α
any␈αreferences␈α
to
␈↓ ↓H␈↓that␈αarea␈α␈↓↓above␈↓␈α␈↓ col␈↓.␈αA␈αreference␈αto␈αthat␈αarea␈αmust␈αbe␈αchanged.␈αWhat␈αis␈αfound␈αin␈αthe␈αreferenced
␈↓ ↓H␈↓cell␈αis␈αnot␈αthe␈αdesired␈αinformation,␈αbut␈αis␈αthe␈αforwarding␈αaddress␈αof␈αthe␈αdesired␈αinformation.␈α
It␈αis
␈↓ ↓H␈↓obvious␈α∞what␈α∞to␈α∞do:␈α∞tell␈α∞the␈α
sender␈α∞what␈α∞the␈α∞change␈α∞of␈α∞address␈α
is.␈α∞ Thus␈α∞the␈α∞␈↓αcdr␈↓-part␈α∞of␈α∞cell␈α
␈↓
77␈↓
␈↓ ↓H␈↓becomes␈α⊃␈↓
100␈↓;␈α⊃the␈α⊃␈↓αcar␈↓-part␈α⊃doesn't␈α⊂change.␈α⊃Cell␈α⊃␈↓
100␈↓␈α⊃refers␈α⊃to␈α⊂two␈α⊃relocated␈α⊃cells;␈α⊃we␈α⊃find␈α⊂their
␈↓ ↓H␈↓forwarding addresses, and cell ␈↓
100␈↓ becomes:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃
␈↓"␈↓ ↓H␈↓
100 ~155~100~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓ ↓H␈↓Similar␈α⊂treatment␈α⊂is␈α⊂given␈α⊂to␈α⊂cell␈α⊂␈↓
155␈↓,␈α⊂modifying␈α⊂the␈α⊂␈↓αcar␈↓-part.␈α⊂ When␈α⊂all␈α⊂cells␈α⊂below␈α⊂␈↓ col␈↓␈α∂are
␈↓ ↓H␈↓updated, the garbage collection is finished. The cells above ␈↓ col␈↓ are all available for the free-list.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓ Is ␈↓ col␈↓ in the free space list after the update phase?
␈↓ ↓H␈↓␈↓↓2.␈↓ Write a LISP algorithm for compacting garbage collection in LISP.
␈↓ ↓H␈↓␈↓↓7.5␈↓ ε≤Representations of Complex Data Structures 357␈↓
␈↓ ↓H␈↓␈↓ ∧¬␈↓↓7.5 Representations of Complex Data Structures␈↓
␈↓ ↓H␈↓In␈αour␈α
discussion␈αof␈α
abstract␈αcontext␈α
free␈αdata␈α
structures␈αin␈α
Section 2.1,␈αwe␈α
isolated␈αthree␈α
kinds␈αof
␈↓ ↓H␈↓structures.
␈↓ ↓H␈↓␈↓ ¬o␈↓
D␈↓ ::= ␈↓
D␈↓β1␈↓ ... ␈↓
D␈↓β1␈↓
␈↓ ↓H␈↓␈↓ ∧Be.g. <seq> ::= ␈↓↓(␈↓<seq elem>␈↓↓,␈↓ ..., <seq elem>␈↓↓)␈↓
␈↓ ↓H␈↓␈↓ ¬Z␈↓
D␈↓ ::= ␈↓
D␈↓β1␈↓ | ␈↓
D␈↓β2␈↓ | ␈↓
D␈↓β3␈↓
␈↓ ↓H␈↓␈↓ ∧oe.g. <seq elem> ::= <indiv> | <seq>
␈↓ ↓H␈↓␈↓ ¬K␈↓
D␈↓ ::= ␈↓
D␈↓β1␈↓ ␈↓
D␈↓β2␈↓ ␈↓
D␈↓β3␈↓... ␈↓
D␈↓βn␈↓
␈↓ ↓H␈↓␈↓ ∧Ze.g. <sexpr> ::= ␈↓α(␈↓<sexpr> . <sexpr>␈↓α)␈↓
␈↓ ↓H␈↓We␈αhave␈αdiscussed␈αthe␈αbehaviorial␈αcharacteristics␈αof␈αalgorithms␈αwhich␈αoperate␈αon␈α
these␈αstructures.
␈↓ ↓H␈↓Now we wish to examine the storage structure aspects of these data structures.
␈↓ ↓H␈↓Corresponding␈α∀to␈α∀these␈α∪three␈α∀data␈α∀structures␈α∀are␈α∪three␈α∀"natural"␈α∀storage␈α∀representations.␈α∪ By
␈↓ ↓H␈↓"natural"␈αwe␈αmean␈αthat␈αeven␈αthough␈αall␈αthese␈αstructures␈αcan␈αbe␈αrepresented␈αas␈αLISP␈αS-expressions,
␈↓ ↓H␈↓for␈α
example,␈α
there␈α
are␈α∞representations␈α
which␈α
might␈α
better␈α
suit␈α∞the␈α
operations␈α
which␈α
we␈α∞expect␈α
to
␈↓ ↓H␈↓perform␈αon␈αthose␈αstructures.␈α Since␈α"natural"␈αis␈αnot␈αa␈αwell-defined␈αterm,␈αwe␈αwill␈αclarify␈αits␈αmeaning
␈↓ ↓H␈↓using examples of context free data structures.
␈↓ ↓H␈↓The␈αfirst␈αtype␈αof␈α
data␈αstructure␈αgiven␈αabove,␈αmaps␈α
naturally␈αonto␈αa␈αrepresentation␈α
which␈αcontains
␈↓ ↓H␈↓information␈α∞that␈α
the␈α∞object␈α
is␈α∞of␈α
type␈α∞␈↓
D␈↓␈α
and␈α∞contains␈α
space␈α∞for␈α
the␈α∞storage␈α
instance␈α∞of␈α∞this␈α
data
␈↓ ↓H␈↓type.␈α∞ Elements␈α∞of␈α∞type␈α∞␈↓
D␈↓␈α∞are␈α∞homogeneous,␈α∞being␈α∞all␈α∞of␈α∞type␈α∞␈↓
D␈↓β1␈↓;␈α∞however␈α∞the␈α∞size␈α∞of␈α∞a␈α∂type␈α∞␈↓
D␈↓
␈↓ ↓H␈↓element␈α_is␈α_indefinite.␈α_ Depending␈α→on␈α_the␈α_operations␈α_which␈α→are␈α_to␈α_be␈α_performed␈α→on␈α_the
␈↓ ↓H␈↓representation,␈α
either␈α
a␈α
list-representation␈α
or␈α∞an␈α
array␈α
representation␈α
is␈α
reasonable␈α
for␈α∞the␈α
storage
␈↓ ↓H␈↓structure. Unless the operations are quite complex, a sequential allocation scheme suffices.
␈↓ ↓H␈↓The␈α∞second␈α∂type␈α∞of␈α∂data␈α∞structure␈α∞is␈α∂frequently␈α∞represented␈α∂as␈α∞a␈α∞pointer.␈α∂ There␈α∞really␈α∂isn't␈α∞any
␈↓ ↓H␈↓storage␈α
allocated␈α
for␈α
objects␈αof␈α
this␈α
type.␈α
Instances␈α
which␈αsatisfy␈α
this␈α
equation␈α
have␈α
their␈αstorage
␈↓ ↓H␈↓requirements␈α
set␈α
by␈α∞one␈α
of␈α
the␈α
␈↓
D␈↓βi␈↓␈α∞alternatives.␈α
We␈α
will␈α
discuss␈α∞pointer␈α
manipulation␈α
in␈α∞LISP␈α
in
␈↓ ↓H␈↓the next section.
␈↓ ↓H␈↓This␈αsection␈αwill␈αdiscuss␈α
the␈αthird␈αabstract␈αdata␈αstructure.␈α
The␈αessential␈αcharacteristic␈αhere␈α
is␈αthat
␈↓ ↓H␈↓instances␈αof␈αthis␈αstructure␈αhave␈αa␈αfixed␈αnumber␈αof␈αcomponents,␈αand␈αthe␈αtypes␈αof␈αthose␈αcomponents
␈↓ ↓H␈↓need␈α~not␈α~be␈α→homogeneous.␈α~Those␈α~components␈α~are␈α→typically␈α~referenced␈α~by␈α~name.␈α→ These
␈↓ ↓H␈↓characteristics␈α
form␈α
a␈α
natural␈αdistinction␈α
between␈α
this␈α
third␈α
class␈αand␈α
the␈α
first␈α
class,␈α
even␈αthough␈α
an
␈↓ ↓H␈↓appropriate encoding would make it possible to represent either class in the other.
␈↓ ↓H␈↓For example, in equations like:
␈↓ ↓H␈↓␈↓ ∧o<sexpr> ::= ␈↓α(␈↓<sexpr> . <sexpr>␈↓α)␈↓ or
␈↓ ↓H␈↓␈↓ ∧z<form> ::= <function>[<arg-list>],
␈↓ ↓H␈↓we reference components by selectors like ␈↓αcar␈↓, ␈↓αcdr␈↓, ␈↓αfunc␈↓ and ␈↓αarglist␈↓.
␈↓ ↓H␈↓␈↓↓358 Storage Structures and Efficiency␈↓ 47.5␈↓
␈↓ ↓H␈↓LISP␈α∞represents␈α∞instances␈α
of␈α∞the␈α∞above␈α
equations␈α∞as␈α∞object␈α
of␈α∞the␈α∞first␈α
and␈α∞second␈α∞types␈α∞of␈α
data
␈↓ ↓H␈↓structure:␈α∩variable-length␈α⊃lists␈α∩of␈α⊃pointers.␈α∩ As␈α∩a␈α⊃result,␈α∩we␈α⊃have␈α∩thought␈α⊃of␈α∩these␈α∩selectors␈α⊃as
␈↓ ↓H␈↓operations␈α∞which␈α∂might␈α∞require␈α∂some␈α∞non-trivial␈α∞amount␈α∂of␈α∞computation␈α∂to␈α∞discover␈α∂the␈α∞desired
␈↓ ↓H␈↓component,␈αbut␈α
as␈αwe␈α
saw␈αin␈α
Section 1.8␈αwhat␈α
is␈αalgorithm␈α
and␈αwhat␈α
is␈αdata␈α
depends␈αon␈αyour␈α
point
␈↓ ↓H␈↓of␈αview.␈αFor␈αexample,␈αwe␈αcould␈αthink␈αof␈αa␈αdotted␈αpair␈αas␈αan␈αarray␈αwhich␈αhas␈αtwo␈αcompoments,␈αone
␈↓ ↓H␈↓referenced␈αby␈α␈↓αcar␈↓,␈α
one␈αreferenced␈αby␈α
␈↓αcdr␈↓.␈α We␈αsay␈α
"array",␈αsince␈αthe␈α
number␈αof␈αcomponents␈αis␈α
know;
␈↓ ↓H␈↓but the element references are done by non-numerical names.
␈↓ ↓H␈↓The␈α
natural␈α
storage␈α
requirements␈α
for␈α
such␈α
objects␈αimply␈α
a␈α
fixed␈α
amount␈α
of␈α
storage.␈α
That␈αstorage
␈↓ ↓H␈↓can␈α
be␈α∞sequentially␈α
allocated␈α
since␈α∞the␈α
size␈α
of␈α∞the␈α
element␈α
will␈α∞not␈α
vary.␈α
The␈α∞representation␈α
must
␈↓ ↓H␈↓also encode the scheme for associating external selector with internal representation. For example:
␈↓"␈↓ ↓H␈↓
⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
~ CAR ~ ~
␈↓"␈↓ ↓H␈↓
εαααααβαααααλ
␈↓"␈↓ ↓H␈↓
~ CDR ~ ~
␈↓"␈↓ ↓H␈↓
%ααααα∀ααααα$
␈↓ ↓H␈↓Notice␈α∂that␈α⊂the␈α∂array␈α⊂referencing␈α∂mechanisms␈α⊂have␈α∂to␈α⊂solve␈α∂a␈α⊂similar␈α∂problem.␈α⊂However,␈α∂array
␈↓ ↓H␈↓representation is such that the dope vector can perform a ␈↓↓calculation␈↓ to locate the element.
␈↓ ↓H␈↓The␈α
storage␈α
element␈α
which␈α
we␈αhave␈α
been␈α
developing␈α
is␈α
called␈αa␈α
␈↓↓record␈↓␈α
([Pop 68]),␈α
or␈α
a␈α␈↓↓structure␈↓
␈↓ ↓H␈↓([Alg 75], [EL1 74]), or a plex ([Han 69])␈↓π 225␈↓.
␈↓ ↓H␈↓Besides␈α∩the␈α∩usual␈α∩constructors,␈α∩selectors␈α∩and␈α⊃recognizers,␈α∩records␈α∩are␈α∩typically␈α∩supplied␈α∩with␈α⊃a
␈↓ ↓H␈↓function␈αto␈α
modify␈αcomponents␈α
of␈αa␈α
structure.␈αThis␈αfunction␈α
is␈αcalled␈α
an␈α␈↓↓updater␈↓.␈α
Just␈αas␈α
we␈αcan
␈↓ ↓H␈↓write␈α⊃␈↓αA[43] ← 56␈↓␈α⊂where␈α⊃␈↓αA␈↓␈α⊂is␈α⊃an␈α⊂array,␈α⊃an␈α⊂updater␈α⊃function␈α⊂would␈α⊃implement␈α⊂a␈α⊃statement␈α⊂like
␈↓ ↓H␈↓␈↓αcar[x] ← (A . B)␈↓.
␈↓ ↓H␈↓Updating␈α
of␈α
simple␈α
variables␈α
is␈α
called␈αassignment.␈α
A␈α
discussion␈α
of␈α
"updating"␈α
of␈α
more␈αgeneral␈α
data
␈↓ ↓H␈↓structures␈α
requires␈α
a␈α
deeper␈α
understanding␈α
of␈α
the␈α
implementation␈α
and␈α
storage␈α
structures.␈α
In␈αthe␈α
case
␈↓ ↓H␈↓of␈α∂LISP,␈α∂it␈α∂requires␈α∂a␈α⊂discussion␈α∂of␈α∂the␈α∂modification␈α∂of␈α∂pointers.␈α⊂That␈α∂is␈α∂the␈α∂topic␈α∂of␈α⊂the␈α∂next
␈↓ ↓H␈↓section.
␈↓ ↓H␈↓␈↓ ¬A␈↓↓7.6 ␈↓αrplaca␈↓↓ and ␈↓αrplacd␈↓↓␈↓α
␈↓ ↓H␈↓The␈αdiscussion␈αin␈αChapter 5␈αdeveloped␈αan␈αimplementation␈αof␈αthe␈αLISP␈αoperations␈αin␈αterms␈αof␈αthe
␈↓ ↓H␈↓manipulation␈α∂of␈α⊂pointers.␈α∂ Those␈α⊂manipulations␈α∂allowed␈α∂the␈α⊂creation␈α∂of␈α⊂new␈α∂structure␈α⊂or␈α∂alloed
␈↓ ↓H␈↓sharing␈αof␈αan␈αexisting␈αstructure.␈αNone␈αof␈αthese␈αoperations␈αinvolved␈αthe␈αmodification␈αof␈αan␈αexisting
␈↓ ↓H␈↓structure.␈α
In␈α
this␈α∞section␈α
we␈α
will␈α∞discuss␈α
some␈α
LISP␈α
coding␈α∞tricks␈α
which␈α
do␈α∞involve␈α
modification
␈↓ ↓H␈↓operations.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 225␈↓ A similar device, called a hunk, has been implemented in MacLISP [Ste pc].
␈↓ ↓H␈↓␈↓↓7.6␈↓ ∪␈↓αrplaca␈↓↓ and ␈↓αrplacd␈↓↓ 359␈↓α
␈↓ ↓H␈↓First consider:
␈↓ ↓H␈↓␈↓α␈↓ β⊗append <= λ[[x;y][null[x] → y; ␈↓
t␈↓α → concat[first[x];append[rest[x];y]]]]␈↓
␈↓ ↓H␈↓This␈α
function␈α
copies␈α
␈↓αx␈↓␈α∞onto␈α
the␈α
front␈α
of␈α
␈↓αy␈↓.␈α∞Note:␈α
␈↓αy␈↓␈α
is␈α
not␈α
copied.␈α∞ Or␈α
recall␈α
the␈α
␈↓αsubst␈↓␈α∞function:␈α
it
␈↓ ↓H␈↓generates␈αa␈αcopy␈αwith␈αthe␈αcorrect␈αsubstitutions␈αmade.␈αLISP␈αoperation␈αmust␈αmake␈αcopies␈αin␈αgeneral,
␈↓ ↓H␈↓otherwise some very unsavory side effects can happen.
␈↓ ↓H␈↓Consider␈α⊂the␈α∂expression␈α⊂␈↓αappend[(A␈α∂B␈α⊂C);(D␈α∂E␈α⊂F)]␈↓.␈α⊂ It␈α∂appears␈α⊂that␈α∂we␈α⊂could␈α∂get␈α⊂the␈α⊂effect␈α∂of
␈↓ ↓H␈↓␈↓αappend␈↓␈α∞by␈α∂␈↓αrest␈↓-ing␈α∞down␈α∂the␈α∞list␈α∂␈↓α(A␈α∞B␈α∂C)␈↓␈α∞until␈α∂we␈α∞found␈α∂the␈α∞terminator,␈α∂and␈α∞then␈α∂replace␈α∞that
␈↓ ↓H␈↓terminator with a pointer to the list ␈↓α(D E F)␈↓. Thus:
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃ ⊂αααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ A ~ #αβαα→~ B ~ #αβαα→~ C ~≤'. . .→~ D ~ #αβαα→~ E ~ #αβαα→~ F ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$ %ααα∀αα$ %ααα∀ααα$ %ααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓The␈α∞resulting␈α∞structure␈α∞does␈α∞indeed␈α∞look␈α∞like␈α∞that␈α∞which␈α∞we␈α∞would␈α∞have␈α∞obtained␈α∂from␈α∞␈↓αappend␈↓.
␈↓ ↓H␈↓The␈α∞operation␈α∞we␈α∂performed␈α∞␈↓↓modified␈↓␈α∞the␈α∂existing␈α∞structure,␈α∞rather␈α∂than␈α∞␈↓↓copying␈↓␈α∞it␈α∂as␈α∞␈↓αappend␈↓
␈↓ ↓H␈↓would have done. Such modifications can cause serious difficulties.
␈↓ ↓H␈↓Let␈α∞us␈α∞call␈α∂the␈α∞modifying␈α∞version␈α∞of␈α∂␈↓αappend␈↓,␈α∞␈↓αnconc␈↓;␈α∞and␈α∞consider␈α∂the␈α∞execution␈α∞of␈α∂the␈α∞following
␈↓ ↓H␈↓sequence of statements:
␈↓ ↓H␈↓α␈↓ ¬_i ← (A,B,C)
␈↓ ↓H␈↓α␈↓ ¬_j ← (D,E,F)
␈↓ ↓H␈↓α␈↓ ¬_k ← nconc[i;j]
␈↓ ↓H␈↓After␈α
execution␈αof␈α
the␈αthird␈α
statement,␈α␈↓αk␈↓␈α
would␈αhave␈α
value␈α␈↓α(A B C D E F)␈↓.␈α
The␈αdifficulty␈α
is␈αthat␈α
␈↓αi␈↓
␈↓ ↓H␈↓would␈α
␈↓↓also␈↓␈α
have␈α
this␈α
value␈α
since␈α
we␈α
modified␈α
the␈α
structure␈α
assigned␈α
to␈α
␈↓αi␈↓.␈α
Also,␈α
any␈α∞value␈α
which
␈↓ ↓H␈↓was␈α_sharing␈α_part␈α↔of␈α_the␈α_structure␈α_of␈α↔␈↓αi␈↓␈α_will␈α_also␈α↔be␈α_changed.␈α_ Language␈α_features␈α↔which
␈↓ ↓H␈↓surreptitiously␈α⊃change␈α⊂values␈α⊃are␈α⊂evil.␈α⊃ Sometimes,␈α⊃however,␈α⊂it␈α⊃is␈α⊂quite␈α⊃useful␈α⊂to␈α⊃be␈α⊃evil.␈α⊂ The
␈↓ ↓H␈↓modification␈α∞procedures,␈α∞such␈α
as␈α∞␈↓αnconc␈↓,␈α∞can␈α∞be␈α
defined␈α∞in␈α∞terms␈α
of␈α∞two␈α∞obscene␈α∞functions:␈α
␈↓αrplaca␈↓
␈↓ ↓H␈↓and ␈↓αrplacd␈↓.
␈↓ ↓H␈↓␈↓↓360 Storage Structures and Efficiency␈↓ 57.6␈↓
␈↓ ↓H␈↓The procedure ␈↓αrplaca␈↓␈↓α[x;y]␈↓ replaces the ␈↓αcar␈↓-part of ␈↓αx␈↓ with ␈↓αy␈↓.
␈↓"␈↓ ↓H␈↓
␈↓αdest␈↓
␈↓αenv␈↓
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααα⊃ ~ ⊂ααααααα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ #αβα⊃ %→ ~ #αβαα ### →
␈↓"␈↓ ↓H␈↓
εαααπαααλ ↓ εαααπαααλ
␈↓"␈↓ ↓H␈↓
# # # ←$ ~ x ~ # βα→α⊃
␈↓"␈↓ ↓H␈↓
~ ~ β→ - - →⊃ εαααβαααλ ~
␈↓"␈↓ ↓H␈↓
εαααβαααλ ~ y ~ #αβ→⊃ ↓
␈↓"␈↓ ↓H␈↓
~ ~ ~ ↓ %ααα∀ααα$ ↓ ~
␈↓"␈↓ ↓H␈↓
# # # ⊂αααπααα⊃ ⊂ααααααα⊃ ~ ↓
␈↓"␈↓ ↓H␈↓
εαααβαααλ ~ # ~ ? ~ ⊂ - - →~ ? ~←$ ~
␈↓"␈↓ ↓H␈↓
~ ~ ~ ⊂→%α|α∀ααα$ | %ααααααα$ ~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ ↑ % - → - →$ ↓
␈↓"␈↓ ↓H␈↓
%←ααα←ααααα←αααα←ααααα←ααααα←ααα$
␈↓"␈↓ ↓H␈↓↓␈↓ ¬CAlgorithm for ␈↓αrplaca␈↓
␈↓ ↓H␈↓The␈α⊂second␈α⊂function␈α⊂is␈α⊃␈↓αrplacd␈↓␈↓α[x;y]␈↓␈α⊂meaning␈α⊂replace␈α⊂the␈α⊂␈↓αcdr␈↓-part␈α⊃of␈α⊂␈↓αx␈↓␈α⊂with␈α⊂␈↓αy␈↓.␈α⊃ The␈α⊂AMBIT/G
␈↓ ↓H␈↓description of this function was given on page 266.
␈↓ ↓H␈↓Now ␈↓αnconc␈↓ can be defined as␈↓π 226␈↓:
␈↓ ↓H␈↓αnconc <= λ[[x;y] prog␈↓ βh[[z]
␈↓ ↓H␈↓α␈↓ β8␈↓ βh[null[x] → return[y]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βhz ← x;
␈↓ ↓H␈↓α␈↓ β8a␈↓ βh[null[cdr[z]] → rplacd[z;y]; return [x]];
␈↓ ↓H␈↓α␈↓ β8␈↓ βhz ←cdr [z];
␈↓ ↓H␈↓α␈↓ β8␈↓ βhgo[a] ]]
␈↓ ↓H␈↓α␈↓Consider:␈↓α␈↓ ∧(prog[[x]␈↓ ¬_x ← (NOTHING CAN GO WRONG);
␈↓ ↓H␈↓α␈↓ ∧(␈↓ ¬_rplacd[cdddr[x];cddr[x]];
␈↓ ↓H␈↓α␈↓ ∧(␈↓ ¬_print[x]]
␈↓ ↓H␈↓We␈α∞can␈α∞use␈α∞␈↓αrplacd␈↓␈α∞to␈α∞generate␈α∞circular␈α
lists.␈α∞ Circular␈α∞lists␈α∞cannot␈α∞be␈α∞generated␈α∞in␈α∞LISP␈α
without
␈↓ ↓H␈↓functions␈α∩like␈α∩␈↓αrplaca␈↓␈α∪and␈α∩␈↓αrplacd␈↓.␈α∩ See␈α∪the␈α∩problem␈α∩on␈α∩page 268.␈α∪ In␈α∩general,␈α∩to␈α∪circularize␈α∩a
␈↓ ↓H␈↓non-empty list, ␈↓αx␈↓, ␈↓αrplacd[last[x];x]␈↓ suffices where:
␈↓ ↓H␈↓␈↓ ∧)␈↓αlast <=λ[[x][null[cdr[x]] → x; ␈↓
t␈↓α → last[cdr[x]]]]␈↓
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 226␈↓␈α
Since␈α
we're␈α
really␈α
involved␈α∞with␈α
the␈α
representation␈α
we␈α
use␈α∞␈↓αcar␈↓␈α
and␈α
␈↓αcdr␈↓␈α
rather␈α
than␈α∞␈↓αfirst␈↓␈α
and
␈↓ ↓H␈↓␈↓αrest␈↓.
␈↓ ↓H␈↓␈↓↓7.6␈↓ ∪␈↓αrplaca␈↓↓ and ␈↓αrplacd␈↓↓ 361␈↓α
␈↓ ↓H␈↓Functions␈α⊗which␈α⊗modify␈α⊗list␈α⊗structure␈α⊗must␈α↔be␈α⊗used␈α⊗with␈α⊗extreme␈α⊗caution.␈α⊗ They␈α↔are␈α⊗not
␈↓ ↓H␈↓recommended␈αfor␈αamateur␈αhacking.␈α They␈αare␈αintroduced␈αhere␈αsimply␈αto␈αshow␈αthat␈αit␈αis␈αpossible␈αto
␈↓ ↓H␈↓improve on the efficiency of pure algorithms by resorting to these coding tricks.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓ What is the effect of evaluating ␈↓αrplacd[x;cdr[x]]␈↓?
␈↓ ↓H␈↓␈↓↓2.␈↓␈αRecall␈αthe␈αproblem␈αon␈αhash␈αconsing␈αon␈αpage 267.␈α There␈αwe␈αwere␈αcontemplating␈αunique␈αstorage
␈↓ ↓H␈↓for all S-exprs. Can such a scheme be reconciled (efficiently) with functions like ␈↓αrplaca␈↓ and ␈↓αrplacd␈↓?
␈↓ ↓H␈↓␈↓↓3.␈↓␈α⊃It␈α⊂has␈α⊃been␈α⊂pointed␈α⊃out␈α⊂that␈α⊃␈↓αrplaca␈↓␈α⊂and␈α⊃␈↓αrplacd␈↓␈α⊂are␈α⊃closely␈α⊂related␈α⊃to␈α⊃assignment␈α⊂statements
␈↓ ↓H␈↓[And 76]. Extend one of our evaluators to recognize expressions like:
␈↓ ↓H␈↓␈↓ ¬A␈↓αcar[␈↓<form>␈↓α] ← ␈↓<form>
␈↓ ↓H␈↓as abbreviations for:
␈↓ ↓H␈↓α␈↓ ¬8rplaca[␈↓<form>; <form>␈↓α]␈↓
␈↓ ↓H␈↓This␈α
extension␈αof␈α
assignment␈αis␈α
obviously␈αnot␈α
restricted␈αto␈α
␈↓αrplaca␈↓␈αbut␈α
could␈αallow␈α
arbitrary␈αforms
␈↓ ↓H␈↓on the left-hand side of an assignment.
␈↓ ↓H␈↓␈↓ ∧S␈↓↓7.7 Applications of ␈↓αrplaca␈↓↓ and ␈↓αrplacd␈↓↓␈↓α
␈↓ ↓H␈↓We␈α⊂begin␈α⊂with␈α∂rather␈α⊂simple␈α⊂examples.␈α⊂Consider␈α∂the␈α⊂problem␈α⊂of␈α∂inserting␈α⊂an␈α⊂element␈α⊂into␈α∂the
␈↓ ↓H␈↓middle␈α∞of␈α
a␈α∞list.␈α
For␈α∞example␈α
let␈α∞␈↓αx␈↓␈α
be␈α∞the␈α
list,␈α∞␈↓α(A␈α
B␈α∞C)␈↓.␈α
If␈α∞we␈α
wished␈α∞to␈α
insert␈α∞an␈α
atom,␈α∞say␈α
␈↓αD␈↓,
␈↓ ↓H␈↓between ␈↓αB␈↓ and ␈↓αC␈↓, we could perform:
␈↓ ↓H␈↓α␈↓ ∧/x ← cons[car[x];cons[cadr[x];cons[D;cddr[x]]]].
␈↓ ↓H␈↓In␈α∪general,␈α∪we␈α∪have␈α∩little␈α∪choice␈α∪but␈α∪to␈α∩recopy␈α∪the␈α∪initial␈α∪segment␈α∩of␈α∪␈↓αx␈↓,␈α∪adding␈α∪␈↓αD␈↓␈α∪into␈α∩the
␈↓ ↓H␈↓appropriate␈α
place.␈α
A␈αsimilar␈α
technique␈α
is␈αobviously␈α
available␈α
to␈α
delete␈αa␈α
specified␈α
element␈αfrom␈α
the
␈↓ ↓H␈↓interior of a list.
␈↓ ↓H␈↓Careful␈α
use␈α
of␈α
␈↓αrplacd␈↓␈α
can,␈α
in␈α
some␈α
instances,␈αreplace␈α
the␈α
heavy␈α
use␈α
of␈α
␈↓αcons␈↓.␈α
␈↓αcons␈↓␈α
always␈αcarries␈α
with
␈↓ ↓H␈↓it the threat of a call on the garbage collector.
␈↓ ↓H␈↓For example, given the list ␈↓α(A B C)␈↓ with pointers, ␈↓αx␈↓ and ␈↓αy␈↓, into it as follows,
␈↓"␈↓ ↓H␈↓
x y
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
↓ ⊂αααπααα⊃ ↓ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%αα→~ A ~ #αβαα∀αα→~ B ~ #αβαα→~ C ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓we could insert the element, ␈↓αD␈↓, ␈↓↓after␈↓ the first element in ␈↓αy␈↓ by:
␈↓ ↓H␈↓␈↓↓362 Storage Structures and Efficiency␈↓ 57.7␈↓
␈↓ ↓H␈↓␈↓ ∧o␈↓αrplacd[y;cons[D;cdr[y]]]␈↓, giving␈↓π 227␈↓:
␈↓"␈↓ ↓H␈↓
x y
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
↓ ⊂αααπααα⊃ ↓ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%αα→~ A ~ #αβαα∀αα→~ B ~ #αβα⊃ ⊂→~ C ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$ ↓ ↑ %ααα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ~
␈↓"␈↓ ↓H␈↓
⊂αααπααα⊃ ↑
␈↓"␈↓ ↓H␈↓
~ D ~ #αβα$
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$
␈↓ ↓H␈↓But␈αas␈α
always,␈αbe␈αwarned␈α
that␈αthe␈αvalue␈α
of␈α␈↓αx␈↓␈αhas␈α
also␈αbeen␈αchanged;␈α
and␈αany␈αS-expr␈α
sharing␈αthe
␈↓ ↓H␈↓list ␈↓αx␈↓ or ␈↓αy␈↓ as a sublist has also been affected.
␈↓ ↓H␈↓We can also use ␈↓αrplacd␈↓ to delete not the ␈↓↓first␈↓, but the next element, in ␈↓αy␈↓ by:
␈↓ ↓H␈↓␈↓ ¬c␈↓αrplacd[y;cddr[y]].␈↓
␈↓ ↓H␈↓Similarly,␈αwe␈α
can␈αuse␈α␈↓αrplaca␈↓␈α
to␈αmodify␈α
an␈αelement␈αin␈α
a␈αlist␈α
(or␈αS-expr).␈α To␈α
change␈αthe␈αfirst␈α
element
␈↓ ↓H␈↓in the list, ␈↓αy␈↓, to the S-expr, ␈↓αz␈↓ use
␈↓ ↓H␈↓␈↓ ε ␈↓αrplaca[y;z]␈↓.
␈↓ ↓H␈↓Notice␈α
that␈αthe␈α
uses␈αof␈α
␈↓αrplacd␈↓␈α
for␈αinsertion␈α
and␈αdeletion␈α
are␈α
couched␈αin␈α
terms␈αof␈α
insert␈α
␈↓↓after␈↓␈αand
␈↓ ↓H␈↓delete ␈↓↓after␈↓, rather than insert ␈↓↓at␈↓ or delete ␈↓↓at␈↓. If you look at a diagram you will see why:
␈↓"␈↓ ↓H␈↓
x
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
↓ ⊂αααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%αα→~ A ~ #αβααααα→~ B ~ #αβαα→~ C ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓To␈α
delete␈α
the␈α
element␈α∞␈↓αB␈↓␈α
requires␈α
modifying␈α
the␈α
␈↓αcdr␈↓-part␈α∞of␈α
the␈α
predecessor␈α
cell;␈α
a␈α∞similar␈α
remark
␈↓ ↓H␈↓applies␈α∩to␈α∩insertion␈α∩at␈α∩a␈α∩specified␈α∩cell.␈α⊃A␈α∩simple,␈α∩perhaps␈α∩inefficient␈α∩scheme,␈α∩to␈α∩support␈α⊃such
␈↓ ↓H␈↓modification␈αwould␈αbe␈αto␈αstart␈αa␈αsecond␈αpointer␈αfrom␈αthe␈αbeginning␈αof␈αthe␈αlist,␈αlooking␈αfor␈αthe␈αcell
␈↓ ↓H␈↓whose ␈↓αcdr␈↓ pointed to the desired spot; then make the modification.
␈↓ ↓H␈↓If␈α∞these␈α∞`modification-␈↓↓at␈↓'␈α∞functions␈α∞were␈α∞to␈α∞be␈α∞performed␈α∞very␈α∞frequently␈α∞then␈α∞it␈α∞might␈α∞be␈α
worth
␈↓ ↓H␈↓starting␈α␈↓↓two␈↓␈αpointers␈αdown␈αthe␈αlist,␈αone␈αat␈α␈↓αx␈↓,␈αone␈αsay␈α␈↓αy␈↓␈αat␈α␈↓αcdr[x]␈↓,␈αas␈αabove.␈α Then␈α␈↓↓testing␈↓␈αcould␈αbe
␈↓ ↓H␈↓done␈α
using␈α
␈↓αy␈↓␈α
and␈αthe␈α
␈↓↓modification␈↓␈α
could␈α
be␈α
done␈αusing␈α
␈↓αx␈↓.␈α
When␈α
we␈α
move␈α␈↓αy␈↓␈α
to␈α
␈↓αcdr[y]␈↓␈α
we␈α
move␈α␈↓αx␈↓␈α
to
␈↓ ↓H␈↓␈↓αcdr[x]␈↓.␈α
If␈α
we␈α
wanted␈α
to␈α
modify␈α
␈↓↓before␈↓␈α
rather␈α
than␈α
␈↓↓at␈↓,␈α
we␈α
could␈α
proliferate␈α
the␈α
`back␈α
pointers',␈α
but␈α
if
␈↓ ↓H␈↓this␈αkind␈αof␈αgenerality␈αis␈αrequired␈αa␈αchange␈αof␈αrepresentation␈αis␈αcalled␈αfor.␈α We␈αmight␈αresort␈αto␈αthe
␈↓ ↓H␈↓double-linking␈αscheme␈αintroduced␈αon␈αpage 228;␈αmore␈αcomplex␈αrepresentations␈αare␈αalso␈αdiscussed␈αin
␈↓ ↓H␈↓detail in [Knu 68], Chapter 2.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 227␈↓ Notice that ␈↓↓one␈↓ ␈↓αcons␈↓ is unavoidable.
␈↓ ↓H␈↓␈↓↓7.7␈↓ π6Applications of ␈↓αrplaca␈↓↓ and ␈↓αrplacd␈↓↓ 363␈↓α
␈↓ ↓H␈↓A␈α
LISP␈α
implementation␈αwhich␈α
stores␈α
p-lists␈α
as␈αlist␈α
structure␈α
would␈αuse␈α
␈↓αrplaca␈↓␈α
and␈α
␈↓αrplacd␈↓␈αheavily;
␈↓ ↓H␈↓for␈α
example,␈αfunctions␈α
which␈αmodify␈α
properties␈αon␈α
the␈αp-lists␈α
would␈αuse␈α
these␈αfunctions.␈α
Here␈αare
␈↓ ↓H␈↓the two p-list manipulating functions, ␈↓αputprop␈↓ and ␈↓αremprop␈↓.
␈↓ ↓H␈↓␈↓αputprop␈↓␈α↔was␈α↔introduced␈α↔on␈α↔page 242.␈α↔ Recall␈α↔that␈α⊗the␈α↔effect␈α↔of␈α↔␈↓αputprop␈↓␈α↔is␈α↔to␈α↔attach␈α⊗an
␈↓ ↓H␈↓␈↓ αHindicator-value␈α∞pair␈α∞to␈α∞an␈α
atom.␈α∞If␈α∞the␈α∞indicator␈α∞is␈α
already␈α∞present␈α∞then␈α∞we␈α∞will␈α
simply
␈↓ ↓H␈↓␈↓ αHchange␈αits␈αvalue;␈αif␈αthe␈αindicator␈αis␈αnot␈αpresent␈αthen␈αwe␈αwill␈αadd␈αthe␈αindicator-value␈αpair
␈↓ ↓H␈↓␈↓ αHto␈α
the␈α∞front␈α
of␈α∞the␈α
p-list.␈α
In␈α∞the␈α
definition␈α∞␈↓αn␈↓␈α
is␈α
an␈α∞atom,␈α
␈↓αi␈↓␈α∞is␈α
an␈α
indicator,␈α∞and␈α
␈↓αv␈↓␈α∞is␈α
the
␈↓ ↓H␈↓␈↓ αHvalue to be stored.
␈↓ ↓H␈↓αputprop <= λ[[n;v;i] prog[[m]
␈↓ ↓H␈↓α␈↓ βH␈↓ βxm ← cdr[n];
␈↓ ↓H␈↓α␈↓ βHa␈↓ βx[eq[car[m];i] → rplaca[cdr[m];v];return[v]];
␈↓ ↓H␈↓α␈↓ βH␈↓ βxm ← cddr[m];
␈↓ ↓H␈↓α␈↓ βH␈↓ βx[null[m] → rplacd[n;cons[i;cons[v;cdr[n]]]];return[v]];
␈↓ ↓H␈↓α␈↓ βH␈↓ βxgo[a] ]]
␈↓ ↓H␈↓Note that extended conditional expressions are used in the definition.
␈↓ ↓H␈↓␈↓αremprop␈↓␈α
was␈αalso␈α
introduced␈α
on␈αpage 242.␈α
␈↓αremprop␈↓␈αis␈α
a␈α
predicate,␈αused␈α
to␈α
remove␈αattribute-value
␈↓ ↓H␈↓␈↓ αHpairs␈α∞from␈α
the␈α∞property␈α
list␈α∞of␈α
an␈α∞atom.␈α
We␈α∞will␈α
capitalize␈α∞of␈α
the␈α∞LISP␈α
␈↓αNIL␈↓-non ␈↓αNIL␈↓
␈↓ ↓H␈↓␈↓ αHtrick␈α∪for␈α∀predicates␈α∪and␈α∀return␈α∪the␈α∀removed␈α∪property␈α∀value␈α∪if␈α∀one␈α∪is␈α∀found.␈α∪ The
␈↓ ↓H␈↓␈↓ αHfollowing implementation of ␈↓αremprop␈↓ does that.
␈↓ ↓H␈↓αremprop <= λ[[n;i] prog[[m]
␈↓ ↓H␈↓α␈↓ β(␈↓ βXm ← n;
␈↓ ↓H␈↓α␈↓ β(a␈↓ βX[eq[cadr[m];i] → rplacd[m;cdddr[m]];return[caddr[m]]];
␈↓ ↓H␈↓α␈↓ β(␈↓ βXm ← cddr[m];
␈↓ ↓H␈↓α␈↓ β(␈↓ βX[null[cdr[m]] → return[␈↓
f␈↓α]]
␈↓ ↓H␈↓α␈↓ β(␈↓ βXgo[a]]]
␈↓ ↓H␈↓Applications␈αof␈α
␈↓αrplacd␈↓␈αwill␈α
occur␈αinside␈α
␈↓αratom␈↓␈αand␈αon␈α
page 369␈αwe␈α
will␈αdevelop␈α
a␈αversion␈αof␈α
LISP's
␈↓ ↓H␈↓parser␈αwhich␈αuses␈αpointer␈αmodification␈αto␈αgain␈αefficiency.␈α Pointer␈αmodification␈αis␈αalso␈αused␈αinside
␈↓ ↓H␈↓the garbage collector. Recall the ␈↓αsweep␈↓ phase of the collector on page 266.
␈↓ ↓H␈↓Finally,␈α
one␈α
of␈αLISP's␈α
less␈α
illustrious␈αuses␈α
of␈α
pointer␈αmodification␈α
is␈α
to␈α"allow"␈α
the␈α
construction␈αof
␈↓ ↓H␈↓self-modifying␈α≠programs.␈α≠ This␈α≤technique␈α≠is␈α≠similar␈α≠to␈α≤the␈α≠machine␈α≠language␈α≤tricks␈α≠of
␈↓ ↓H␈↓self-modifying␈α∂code␈α∂and␈α∂should␈α∂be␈α∂used␈α⊂with␈α∂similar␈α∂frequency.␈α∂ The␈α∂freedom␈α∂to␈α⊂hang␈α∂yourself
␈↓ ↓H␈↓should␈α∂not␈α∂be␈α⊂construed␈α∂as␈α∂an␈α⊂invitation,␈α∂but␈α∂it␈α⊂again␈α∂points␈α∂out␈α⊂the␈α∂similarities␈α∂of␈α⊂LISP␈α∂with
␈↓ ↓H␈↓machine language and highlights the differences with LISP's contemporaries.
␈↓ ↓H␈↓LISP's␈α~central␈α→processor␈α~␈↓αeval␈↓␈α~operates␈α→by␈α~traversing␈α~and␈α→interpreting␈α~the␈α~data␈α→structure
␈↓ ↓H␈↓representation␈α⊃of␈α∩the␈α⊃program;␈α⊃that␈α∩data␈α⊃structure␈α⊃is␈α∩also␈α⊃open␈α⊃for␈α∩inspection␈α⊃by␈α∩LISP's␈α⊃data
␈↓ ↓H␈↓structure␈α~manipulating␈α→functions.␈α~ Since␈α~we␈α→now␈α~have␈α→list-modifying␈α~functions,␈α~we␈α→could
␈↓ ↓H␈↓␈↓↓364 Storage Structures and Efficiency␈↓ 57.7␈↓
␈↓ ↓H␈↓conceivable␈α
modify␈α
a␈α
program␈α
by␈α
changing␈α
its␈α
internal␈α
structure.␈α
Indeed␈α
we␈α
can␈α
write␈α
a␈α
program
␈↓ ↓H␈↓which modifies its ␈↓↓own␈↓ structure.
␈↓ ↓H␈↓Here's one:
␈↓ ↓H␈↓αfoo <= λ[[x] prog[[y;z]
␈↓ ↓H␈↓α␈↓ β_␈↓ β8z←1;
␈↓ ↓H␈↓α␈↓ β_␈↓ β8y←sixth[body[foo]];
␈↓ ↓H␈↓α␈↓ β_a␈↓ β8print[x];
␈↓ ↓H␈↓α␈↓ β_␈↓ β8rplaca[rest[y];z←add1[z]];
␈↓ ↓H␈↓α␈↓ β_␈↓ β8go[a] ]]
␈↓ ↓H␈↓The␈α∩mystery␈α∩created␈α∩by␈α∩␈↓αy␈↓␈α⊃is␈α∩a␈α∩pointer␈α∩into␈α∩the␈α⊃representation␈α∩of␈α∩the␈α∩statement␈α∩␈↓αprint[x]␈↓;␈α⊃that
␈↓ ↓H␈↓representation␈αis␈α
␈↓α(PRINT X)␈↓.␈αTherefore␈αthe␈α
effect␈αof␈αthe␈α
first␈α␈↓αrplaca␈↓␈αis␈α
to␈αchange␈α
␈↓α(PRINT X)␈↓␈αto
␈↓ ↓H␈↓␈↓α(PRINT 2)␈↓.␈α Subsequent␈α
passes␈αthrough␈αthe␈α
loop␈αwill␈α
change␈αthe␈αstatement␈α
to␈αprint␈α
␈↓α3,␈α4,␈α...␈↓.␈α
There
␈↓ ↓H␈↓really isn't much that can be said about such a program.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓I.␈α
More␈α
on␈α
␈↓αratom␈↓.␈α
Recall␈α
the␈α
discussion␈αof␈α
␈↓αratom␈↓␈α
in␈α
Section 5.11␈α
and␈α
Section 5.12.␈α
Now␈α
that␈αyou
␈↓ ↓H␈↓know about ␈↓αrplaca␈↓ and ␈↓αrplacd␈↓ write a more detailed version of ␈↓αratom␈↓.
␈↓ ↓H␈↓II.␈αRecall␈αthe␈αfunction␈αwhich␈αreverses␈αthe␈αtop-level␈αelements␈αof␈αa␈αlist.␈α On␈αpage 46␈αand␈αpage 47␈αwe
␈↓ ↓H␈↓wrote␈αit␈αin␈αvarious␈αstyles␈αand␈αwith␈α
varying␈αdegrees␈αof␈αefficiency.␈α All␈αof␈αthese␈αfunctions␈α
used␈α␈↓αcons␈↓;
␈↓ ↓H␈↓however␈α
it␈α
is␈α
clear␈α
that␈α
we␈αshould␈α
be␈α
able␈α
to␈α
reverse␈α
a␈αlist␈α
without␈α
using␈α
␈↓↓any␈↓␈α
new␈α
cells.␈α Express
␈↓ ↓H␈↓this algorithm as a LISP function. If you use ␈↓αprog␈↓ don't use any ␈↓αprog␈↓-variables.
␈↓ ↓H␈↓␈↓ ¬w␈↓↓7.8 Numbers␈↓
␈↓ ↓H␈↓In␈α
most␈α
implementations␈α
of␈αLISP,␈α
numbers␈α
are␈α
stored␈αas␈α
very␈α
simple␈α
kinds␈αof␈α
atoms:␈α
they␈α
do␈αnot
␈↓ ↓H␈↓need␈α
print␈αnames,␈α
but␈αsince␈α
we␈αshould␈α
probably␈αallow␈α
fixed␈αand␈α
floating␈αpoint␈α
representation,␈αwe
␈↓ ↓H␈↓do need indicators for these properties. Thus:
␈↓ ↓H␈↓␈↓↓7.8␈↓
Numbers 365␈↓
␈↓"␈↓ ↓H␈↓
fixed-point 1
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααααπααα⊃ ⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ FIXNUM ~ #αβαα→~ 1 ~
␈↓"␈↓ ↓H␈↓
%αααααααα∀ααα$ %ααααα$
␈↓"␈↓ ↓H␈↓
floating-point 1
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααααπααα⊃ ⊂ααααααααααααααααααααααα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ FLONUM ~ #αβαα→~ <machine rep of 1.0> ~
␈↓"␈↓ ↓H␈↓
%αααααααα∀ααα$ %ααααααααααααααααααααααα$
␈↓ ↓H␈↓In␈α⊂this␈α⊃representation,␈α⊂the␈α⊃number␈α⊂is␈α⊃stored␈α⊂in␈α⊂FWS␈α⊃and␈α⊂the␈α⊃type␈α⊂indicator␈α⊃is␈α⊂indicated␈α⊃by␈α⊂a
␈↓ ↓H␈↓minimal␈α∂property␈α∂list.␈α∞ This␈α∂representation␈α∂is␈α∞a␈α∂bit␈α∂expensive␈α∞in␈α∂space␈α∂and␈α∞can␈α∂be␈α∂expensive␈α∞to
␈↓ ↓H␈↓manipulate with arithmetic operators. Several tricks have been used to improve arithmetic in LISP.
␈↓ ↓H␈↓Assume␈α∞that␈α∞the␈α∞addressing␈α∞space␈α∞of␈α∞the␈α∞machine␈α∞is␈α
2␈↓π18␈↓␈α∞and␈α∞that␈α∞the␈α∞usual␈α∞size␈α∞of␈α∞a␈α∞LISP␈α
core
␈↓ ↓H␈↓image␈α⊂is␈α⊂significantly␈α⊂smaller,␈α⊂say,␈α⊂N.␈α⊂ Then␈α∂all␈α⊂memory␈α⊂address␈α⊂references␈α⊂greater␈α⊂than␈α⊂N␈α∂are
␈↓ ↓H␈↓illegal␈α(and␈αtrapped␈αby␈αthe␈αmonitor).␈α What␈αwe␈α
will␈αdo␈αis␈αuse␈αthese␈αillegal␈αaddresses␈αto␈αencode␈α
some
␈↓ ↓H␈↓of␈α∂the␈α∂smaller␈α∂positive␈α∂and␈α∂negative␈α∂integers,␈α∞mapping␈α∂zero␈α∂on␈α∂the␈α∂middle␈α∂address,␈α∂the␈α∞positive
␈↓ ↓H␈↓numbers␈α⊃to␈α⊃lower␈α⊃addresses␈α⊃and␈α⊃the␈α∩negatives␈α⊃onto␈α⊃the␈α⊃higher␈α⊃addresses.␈α⊃ Thus␈α∩these␈α⊃smaller
␈↓ ↓H␈↓integers,␈α∞called␈α∞␈↓↓inums␈↓,␈α∞are␈α∞represented␈α∞by␈α
pointers␈α∞outside␈α∞of␈α∞the␈α∞normal␈α∞LISP␈α∞addressing␈α
space.
␈↓ ↓H␈↓This␈α
trick␈α
can␈α
considerably␈α
decrease␈α
the␈αstorage␈α
requirements␈α
for␈α
jobs␈α
heavily␈α
using␈αsmall␈α
numbers.
␈↓ ↓H␈↓(Numbers are not usually stored uniquely).
␈↓ ↓H␈↓␈↓↓366 Storage Structures and Efficiency␈↓ 47.8␈↓
␈↓"␈↓ ↓H␈↓
⊂αααααααααα⊃ 2␈↓π18␈↓
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~ m ␈↓<␈↓
0
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~ m = 0
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~ m ␈↓>␈↓
0
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
εααααααααααλ N
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
~␈↓ βx~
␈↓"␈↓ ↓H␈↓
%αααααααααα$ 0
␈↓"␈↓ ↓H␈↓
␈↓↓␈↓ ¬0Picture of INUM Space␈↓
␈↓ ↓H␈↓The␈α
INUM␈αrepresentation␈α
takes␈α
less␈αspace␈α
but␈αadds␈α
an␈α
additional␈αcomplexity:␈α
now␈α
the␈αarithmetic
␈↓ ↓H␈↓operators have to deal with three different kinds of numbers.
␈↓ ↓H␈↓The␈αMacLISP␈α([Moo 74])␈αimplementation␈αuses␈αa␈αdifferent␈αrepresentation␈αfor␈αnumbers␈↓π 228␈↓.␈α In␈αthat
␈↓ ↓H␈↓implementation,␈α⊃two␈α∩spaces␈α⊃are␈α∩allocated␈α⊃for␈α∩number␈α⊃storage:␈α∩FIXNUM␈α⊃space␈α∩and␈α⊃FLONUM
␈↓ ↓H␈↓space.␈α⊂This␈α⊂makes␈α⊂a␈α⊂more␈α⊂compact␈α⊃representation␈α⊂since␈α⊂the␈α⊂type␈α⊂information␈α⊂is␈α⊂implied␈α⊃in␈α⊂the
␈↓ ↓H␈↓address␈α∞of␈α∞the␈α∞object,␈α∞rather␈α∞than␈α∞explicitly␈α
stored.␈α∞To␈α∞those␈α∞basic␈α∞spaces␈α∞we␈α∞add␈α∞two␈α
temporary
␈↓ ↓H␈↓stack areas: FIXPDL and FLOPDL. These areas are used for temporary arithmetic computation.
␈↓ ↓H␈↓The␈αtemporary␈αareas␈αwork␈αin␈αconjunction␈αwith␈αa␈αtype␈αdeclaration␈αoption␈αavailable␈αin␈αMacLISP.␈αIf
␈↓ ↓H␈↓we␈α
know␈α∞that␈α
certain␈α
variables␈α∞are␈α
␈↓↓always␈↓␈α∞going␈α
to␈α
be␈α∞used␈α
as␈α
numbers␈α∞in␈α
a␈α∞particular␈α
function
␈↓ ↓H␈↓then␈α∂we␈α∂can␈α∂compile␈α∂better␈α⊂code.␈α∂Assume␈α∂␈↓αx␈↓␈α∂and␈α∂␈↓αy␈↓␈α∂are␈α⊂to␈α∂be␈α∂used␈α∂␈↓↓only␈↓␈α∂as␈α∂FIXNUMs␈α⊂within␈α∂a
␈↓ ↓H␈↓function␈α∞␈↓αf␈↓;␈α∞we␈α
would␈α∞make␈α∞such␈α
declarations␈α∞for␈α∞the␈α
LISP␈α∞compiler␈α∞just␈α
as␈α∞we␈α∞can␈α∞declare␈α
some
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 228␈↓␈α∞Much␈α∞care␈α∞went␈α∞into␈α∞the␈α∞MacLISP␈α
number␈α∞handling␈α∞since␈α∞it␈α∞is␈α∞used␈α∞as␈α∞the␈α
implementation
␈↓ ↓H␈↓language␈α_for␈α_MACSYMA␈α→([MAC 74], [Wan 75], [Mos 74]),␈α_a␈α_large␈α_algebraic␈α→and␈α_symbolic
␈↓ ↓H␈↓mathematics␈α
system.␈α
MacLISP's␈α
efficient␈α
number␈α
facilities,␈α
coupled␈α
with␈α
its␈α
optimizing␈α
compiler,␈α
has
␈↓ ↓H␈↓resulted␈αin␈αthe␈αproduction␈α
of␈αcompiled␈αcode␈αwhich␈αis␈α
more␈αefficient␈αthan␈αthat␈αproduced␈α
by␈αDEC's
␈↓ ↓H␈↓FORTRAN compiler; [Fat 73].
␈↓ ↓H␈↓␈↓↓7.8␈↓
Numbers 367␈↓
␈↓ ↓H␈↓variables␈αas␈α"special"␈αto␈αLISP␈αcompilers.␈α When␈αwe␈αallocate␈αspace␈αfor␈α␈↓αx␈↓␈αand␈α␈↓αy␈↓,␈αwe␈αallocate␈αspace␈αon
␈↓ ↓H␈↓the␈αtop␈αof␈αFIXPDL.␈αWithin␈α␈↓αf␈↓␈αthe␈αarithmetic␈αoperations␈αuse␈αthe␈αhardware␈αarithmetic␈αand␈αreference
␈↓ ↓H␈↓the␈α
stack␈αelements.␈α
The␈α
stack␈αelements␈α
can␈αbe␈α
passed␈α
to␈αother␈α
arithmetic␈αfunctions␈α
called␈α
within␈α␈↓αf␈↓
␈↓ ↓H␈↓and␈α⊂no␈α⊂permanent␈α⊂storage␈α⊃need␈α⊂be␈α⊂allocated␈α⊂in␈α⊂FIXNUM␈α⊃space␈α⊂until␈α⊂later.␈α⊂ The␈α⊃efficiency␈α⊂of
␈↓ ↓H␈↓arithmetic␈α∩operations␈α∩is␈α∩dependent␈α∩on␈α∩the␈α∩existence␈α∩of␈α∩special␈α∩hardware␈α∩instructions␈α∩for␈α∩such
␈↓ ↓H␈↓arithmetic.␈α⊂ However,␈α⊂special␈α⊂hardware␈α⊂also␈α⊃places␈α⊂limits␈α⊂on␈α⊂the␈α⊂arithmetic␈α⊂capabilities␈α⊃of␈α⊂most
␈↓ ↓H␈↓languages: arithmetic is limited by the word size. LISP is able to overcome such limitations.
␈↓ ↓H␈↓Most␈α
numerically␈αoriented␈α
programs␈αare␈α
faced␈αat␈α
some␈αtime␈α
with␈αoverflow.␈α
That␈αis,␈α
they␈αattempt␈α
to
␈↓ ↓H␈↓construct␈αa␈α
number␈αwhich␈α
is␈αtoo␈α
large␈αto␈αbe␈α
represented␈αin␈α
one␈αmachine␈α
location.␈α There␈α
are␈αnow
␈↓ ↓H␈↓several␈αversions␈αof␈αLISP␈αwhich␈αwill␈α
automatically␈αchange␈αrepresentation␈αwhen␈αfaced␈αwith␈α
overflow.
␈↓ ↓H␈↓This␈α
scheme␈α
is␈α
called␈αarbitrary␈α
precision␈α
arithmetic␈α
and␈α
has␈αbeen␈α
implemented␈α
for␈α
both␈αfixed␈α
point
␈↓ ↓H␈↓and␈α⊃floating␈α⊃point␈α⊂numbers.␈α⊃We␈α⊃will␈α⊂describe␈α⊃a␈α⊃representation␈α⊂for␈α⊃fixed␈α⊃point␈α⊃numbers␈α⊂called
␈↓ ↓H␈↓Bignums; they could have the following structure:
␈↓"␈↓ ↓H␈↓
positive big number
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ POSNUM ~ #αβαα→~ # ~ #αβα→ ... →~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αααααααα∀ααα$ %αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
N␈↓β0␈↓
N␈↓βn␈↓
␈↓"␈↓ ↓H␈↓
negative big number
␈↓"␈↓ ↓H␈↓
~
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
~ ⊂ααααααααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%→ ~ NEGNUM ~ #αβαα→~ # ~ #αβα→ ... →~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αααααααα∀ααα$ %αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
↓ ↓
␈↓"␈↓ ↓H␈↓
N␈↓β0␈↓
N␈↓βn␈↓
␈↓"␈↓ ↓H␈↓
␈↓ ¬-␈↓↓Structure of a BIGNUM␈↓
␈↓ ↓H␈↓The value of Bignum is given by:
␈↓ ↓H␈↓␈↓ ¬9␈↓εb␈↓(N␈↓β0␈↓ + ␈↓εa␈↓N␈↓β1␈↓+ ... + ␈↓εa␈↓πn␈↓N␈↓βn␈↓)
␈↓ ↓H␈↓where␈α
␈↓εb␈↓␈α
is␈α∞either␈α
+␈α
or␈α
-␈α∞and␈α
␈↓εa␈↓-1␈α
is␈α∞the␈α
largest␈α
number␈α
representable␈α∞in␈α
one␈α
machine␈α∞word.␈α
The
␈↓ ↓H␈↓translations␈α∪Bignums␈α∩and␈α∪the␈α∪other␈α∩numeric␈α∪representations␈α∪is␈α∩done␈α∪automatically␈α∪within␈α∩the
␈↓ ↓H␈↓evaluator.
␈↓ ↓H␈↓On␈α
most␈α
implementations␈α
on␈α∞LISP,␈α
no␈α
attempt␈α
is␈α
made␈α∞to␈α
store␈α
numbers␈α
uniquely.␈α
Thus␈α∞␈↓αeq␈↓␈α
will
␈↓ ↓H␈↓not␈α
work␈α
on␈α
numbers␈α
other␈αthan␈α
INUMs;␈α
either␈α
␈↓αequal␈↓␈α
is␈αextended␈α
for␈α
numbers␈α
or␈α
a␈αspecial␈α
equality
␈↓ ↓H␈↓predicate for numbers is provided.
␈↓ ↓H␈↓␈↓↓368 Storage Structures and Efficiency␈↓ 57.9␈↓
␈↓ ↓H␈↓␈↓ ¬!␈↓↓7.9 Stacks and Threading␈↓
␈↓ ↓H␈↓Though␈α∃recursive␈α∀descriptions␈α∃of␈α∀algorithms␈α∃are␈α∀usually␈α∃more␈α∀illuminating␈α∃than␈α∃the␈α∀typical
␈↓ ↓H␈↓machine-oriented␈α
counterparts,␈αit␈α
is␈α
frequently␈αmore␈α
efficient␈α
to␈αencode␈α
those␈α
algorithms␈αin␈α
manners
␈↓ ↓H␈↓which␈α⊂can␈α⊃take␈α⊂advantage␈α⊂of␈α⊃contemporary␈α⊂hardware.␈α⊂This␈α⊃section␈α⊂will␈α⊂discuss␈α⊃two␈α⊂techniques
␈↓ ↓H␈↓which "unwind" the recursion and typically lead to faster execution.
␈↓ ↓H␈↓Recall␈α∩the␈α∪marking␈α∩phase␈α∩of␈α∪a␈α∩garbage␈α∩collector␈α∪in␈α∩Section 5.14.␈α∩There␈α∪we␈α∩wrote␈α∩␈↓αmark␈↓␈α∪as␈α∩a
␈↓ ↓H␈↓recursive algorithm. We could equally well write ␈↓αmark␈↓ using an explicit stack:
␈↓ ↓H␈↓αmark <= λ[[tr]prog[[st]
␈↓ ↓H␈↓α␈↓ α_loop␈↓ αx[is_marked[tr] → go[chk_st];
␈↓ ↓H␈↓α␈↓ α_␈↓ αx is_full_wd[tr]→ markA[tr];go[chk_st];
␈↓ ↓H␈↓α␈↓ α_␈↓ αx is_free_wd[tr]→␈↓ ∧hst←push[cdr[tr];st];
␈↓ ↓H␈↓α␈↓ α_␈↓ αx␈↓ ∧hmarkA[tr];
␈↓ ↓H␈↓α␈↓ α_␈↓ αx␈↓ ∧htr←car[tr];go[loop]];
␈↓ ↓H␈↓α␈↓ α_␈↓ αx ␈↓
t␈↓α → go[chk_st]]; ␈↓π 229␈↓α
␈↓ ↓H␈↓α␈↓ α_chk_st␈↓ αx[null[st] → return[␈↓
t␈↓α]];
␈↓ ↓H␈↓α␈↓ α_␈↓ αxtr←top[st];
␈↓ ↓H␈↓α␈↓ α_␈↓ αxst←pop[st];
␈↓ ↓H␈↓α␈↓ α_␈↓ αxgo[loop] ]]
␈↓ ↓H␈↓αpush <= λ[[i;st] concat[i;st]]
␈↓ ↓H␈↓αtop <= λ[[st] first[st]]
␈↓ ↓H␈↓αpop <= λ[[st] rest[st]]
␈↓ ↓H␈↓Notice␈α
that␈αwe␈α
only␈α
save␈αthe␈α
␈↓αcdr␈↓-node␈α
in␈αthe␈α
stack;␈α
even␈αat␈α
that␈α
the␈αstack␈α
grows␈α
proportionally␈αto
␈↓ ↓H␈↓the␈α
depth␈α∞of␈α
the␈α∞tree␈α
being␈α∞traversed.␈α
See␈α
the␈α∞problem␈α
on␈α∞page 369.␈α
The␈α∞technique␈α
of␈α∞using␈α
an
␈↓ ↓H␈↓explicit stack sometimes is more intuitive and sometimes will lead to faster execution.
␈↓ ↓H␈↓The␈α
second␈α
technique␈α
is␈αmore␈α
tricky␈α
but␈α
will␈α
lead␈αto␈α
significant␈α
pay-offs␈α
in␈α
execution␈αtime␈↓π 230␈↓.␈α
The
␈↓ ↓H␈↓technique␈α
is␈α
called␈α
␈↓↓threading␈↓.␈α
The␈α
basis␈α
for␈α∞threading␈α
is␈α
a␈α
desire␈α
to␈α
traverse␈α
tree-structures␈α∞in␈α
a
␈↓ ↓H␈↓more␈α∩efficient␈α⊃fashion␈α∩than␈α⊃that␈α∩typically␈α∩available␈α⊃in␈α∩recursion␈α⊃or␈α∩via␈α⊃stacks.␈α∩Recall␈α∩that␈α⊃on
␈↓ ↓H␈↓page 228␈α∂we␈α∞surmised␈α∂that␈α∂␈↓↓double-linking␈↓␈α∞might␈α∂be␈α∞advantageous␈α∂in␈α∂moving␈α∞up␈α∂and␈α∂down␈α∞the
␈↓ ↓H␈↓"spine"␈αof␈αa␈αtree␈αstructure.␈α Double␈αlinks␈αwould␈αallow␈αus␈αto␈αfind␈αthe␈αsuccessors␈αand␈αpredecessors␈αof
␈↓ ↓H␈↓nodes␈α
easily.␈α
However␈α
the␈αextra␈α
link␈α
gives␈α
us␈αno␈α
help␈α
if␈α
we␈α
wish␈αto␈α
descend␈α
into␈α
the␈αsubstructure.␈α
It
␈↓ ↓H␈↓is␈α
this␈α
area␈α
to␈α
which␈α
threading␈α
addresses␈α
itself:␈α
descent␈α
into␈α
tree␈α
structure,␈α
and␈α
in␈αfact,␈α
non-recursive
␈↓ ↓H␈↓tree traversal. Threading comes in various flavors; we will now discuss a few.
␈↓ ↓H␈↓Look␈α∂at␈α∂the␈α∂new␈α∂␈↓αmark␈↓-er␈α∂above;␈α∂you␈α∂should␈α⊂notice␈α∂that␈α∂for␈α∂a␈α∂␈↓↓fixed␈↓␈α∂tree␈α∂and␈α∂a␈α∂␈↓↓fixed␈↓␈α⊂order␈α∂of
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓α␈↓π 229␈↓α ␈↓This branch of the conditional could be omitted and the effect would be the same.
␈↓ ↓H␈↓␈↓π 230␈↓ with a proportional loss in clarity of code
␈↓ ↓H␈↓␈↓↓7.9␈↓ λRStacks and Threading 369␈↓
␈↓ ↓H␈↓traversal,␈αthat␈αany␈αtwo␈αapplications␈αof␈αmarking␈αwill␈αhave␈αthe␈αsame␈αpattern␈αof␈αbehavior.␈αThe␈αorder
␈↓ ↓H␈↓of␈αvisitiation␈αto␈αeach␈αnode␈αwill␈αobviously␈αbe␈αthe␈αsame,␈αbut␈αthe␈αdynamic␈αchanges␈αin␈αthe␈αstate␈αof␈αthe
␈↓ ↓H␈↓stack␈α
will␈α␈↓↓also␈↓␈α
be␈αthe␈α
same.␈αInstead␈α
of␈αreplicating␈α
the␈αportion␈α
of␈αthe␈α
stack,␈αit␈α
might␈αbe␈α
possible␈αto
␈↓ ↓H␈↓store␈αthe␈αstack␈αinformation␈αin␈α
the␈αstructure␈αitself.␈α This␈αtechnique␈α
of␈αhiding␈αthe␈αcontrol␈αstructure␈α
in
␈↓ ↓H␈↓the␈α⊃data␈α⊂structure␈α⊃is␈α⊃called␈α⊂threading.␈α⊃The␈α⊂general␈α⊃application␈α⊃of␈α⊂threading␈α⊃is␈α⊃of␈α⊂questionable
␈↓ ↓H␈↓utility.␈α
It␈α
typically␈α
requires␈α
a␈α
more␈α
complex␈α∞data␈α
structure:␈α
we␈α
must␈α
be␈α
able␈α
to␈α
store␈α∞both␈α
threads
␈↓ ↓H␈↓and␈α∂links.␈α⊂The␈α∂traversing␈α⊂algorithms␈α∂also␈α⊂become␈α∂more␈α∂complex:␈α⊂we␈α∂obviously␈α⊂must␈α∂be␈α⊂able␈α∂to
␈↓ ↓H␈↓recognize␈α
the␈αdifference␈α
between␈α
control␈αthreads␈α
and␈αdata␈α
links.␈α
Care␈αmust␈α
also␈α
be␈αtaken␈α
if␈αwe␈α
wish
␈↓ ↓H␈↓to share threaded list structure. See [Knu 68] for a complete discussion of the techniques and tricks.
␈↓ ↓H␈↓We␈αare␈α
not␈αabout␈α
to␈αcomplicate␈αthe␈α
LISP␈αstructures,␈α
but␈αdispensing␈αwith␈α
a␈αstack,␈α
be␈αit␈α
implicit␈αor
␈↓ ↓H␈↓explict,␈α␈↓↓does␈↓␈αhave␈αsome␈αmerits.␈αWhat␈αwe␈α␈↓↓can␈↓␈αdo␈αin␈αLISP␈αis␈αstrike␈αa␈αcompromise.␈αInstead␈αof␈αstoring
␈↓ ↓H␈↓the␈α
threads␈αpermanently␈α
in␈αthe␈α
structure,␈αthere␈α
are␈αsignificant␈α
applications␈αof␈α
threading␈α
where␈αwe
␈↓ ↓H␈↓can␈α⊂␈↓↓temporarily␈↓␈α⊂store␈α⊂threads␈α⊂as␈α⊂we␈α⊂traverse␈α⊂trees.␈α∂The␈α⊂first␈α⊂application␈α⊂is␈α⊂in␈α⊂the␈α⊂design␈α⊂of␈α∂a
␈↓ ↓H␈↓non-recursive␈α∂␈↓αread␈↓␈α⊂program;␈α∂the␈α⊂second␈α∂application␈α∂we␈α⊂will␈α∂describe␈α⊂is␈α∂in␈α∂the␈α⊂mark␈α∂phase␈α⊂of␈α∂a
␈↓ ↓H␈↓garbage collector.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓With␈αa␈α
little␈αmore␈αtesting␈α
before␈αstacking␈α
we␈αcan␈αsignificantly␈α
cut␈αdown␈αthe␈α
number␈αof␈α
␈↓αpush␈↓es␈αwe
␈↓ ↓H␈↓have␈α∞to␈α
do.␈α∞Namely,␈α
if␈α∞some␈α∞of␈α
the␈α∞branches␈α
point␈α∞immediately␈α∞to␈α
atoms␈α∞we␈α
might␈α∞as␈α∞well␈α
mark
␈↓ ↓H␈↓them␈α∂at␈α∂that␈α⊂time␈α∂and␈α∂proceed␈α∂without␈α⊂doing␈α∂a␈α∂stack␈α∂operation.␈α⊂Only␈α∂when␈α∂both␈α⊂branches␈α∂are
␈↓ ↓H␈↓"non-atomic" do we need stack the ␈↓αcdr␈↓. Write such an algorithm.
␈↓ ↓H␈↓␈↓ ¬"␈↓↓7.10 A Non-recursive ␈↓αread␈↓↓␈↓α
␈↓ ↓H␈↓The␈αoriginal␈α␈↓αread␈↓␈αalgorithm␈αof␈αSection 5.11␈αis␈αa␈αgood␈αexample␈αof␈αa␈αclear␈αrecursive␈αalgorithm;␈α
it␈αis
␈↓ ↓H␈↓reasonably straightforward to follow the flow of the algorithm.
␈↓ ↓H␈↓However,␈αnow␈αthat␈αwe␈αunderstand␈αwhat␈αthe␈αrun-time␈αbehavior␈αof␈αsuch␈αa␈αrecursive␈αprogram␈αis,␈αwe
␈↓ ↓H␈↓can␈αsee␈α
that␈α␈↓αread␈↓␈α
and␈αfriends␈α
are␈αa␈αdrain␈α
on␈α␈↓↓two␈↓␈α
resouces:␈αthey␈α
use␈αfree-space␈α
to␈α␈↓αcons␈↓-up␈αthe␈α
S-expr
␈↓ ↓H␈↓representation␈α∂of␈α∂the␈α∞input;␈α∂they␈α∂use␈α∂the␈α∞run-time␈α∂stack␈α∂for␈α∞handling␈α∂the␈α∂implementation␈α∂of␈α∞the
␈↓ ↓H␈↓recursion␈α∂and␈α∞for␈α∂saving␈α∞parameters␈α∂and␈α∞intermediate␈α∂computations.␈α∞A␈α∂deeply␈α∂nested␈α∞expression
␈↓ ↓H␈↓will␈αuse␈α
a␈αlot␈α
of␈αthe␈α
run-time␈αstack.␈α
Clearly,␈αthere␈α
is␈αnothing␈α
we␈αcan␈α
do␈αabout␈α
the␈αdrain␈α
on␈αthe␈α
free
␈↓ ↓H␈↓lists␈↓π 231␈↓,␈αbut␈α
we␈α␈↓↓can␈↓␈α
dispense␈αwith␈α
the␈αrun-time␈α
stack␈αby␈α
threading.␈α We␈α
can␈αin␈α
fact␈αdo␈α
so␈αwithout␈α
a
␈↓ ↓H␈↓proportional␈αincrease␈αin␈αthe␈αuse␈αof␈αcells␈αin␈αfree␈αspace;␈αindeed␈αwe␈αneed␈αonly␈α␈↓↓one␈↓␈αadditional␈αfree␈αcell,
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 231␈↓␈αWe␈αprobably␈αwill␈αbe␈αdrawing␈αon␈αthe␈αfull␈αword␈αarea␈αfor␈αprint␈αname␈αstorage␈αas␈αwell␈αas␈αthe␈αfree
␈↓ ↓H␈↓space area for list structure storage.
␈↓ ↓H␈↓␈↓↓370 Storage Structures and Efficiency␈↓ )7.10␈↓
␈↓ ↓H␈↓regardless␈αof␈αthe␈αcomplexity␈αof␈αthe␈αinput!␈αThis␈αis␈αtruly␈αa␈αwin␈αfor␈αefficiency;␈αit␈αwill␈αbe␈αa␈αbig␈αloss␈αfor
␈↓ ↓H␈↓clarity.␈α⊂But␈α⊂again␈α⊂that's␈α⊃why␈α⊂this␈α⊂section␈α⊂on␈α⊃storage␈α⊂and␈α⊂efficiency␈α⊂is␈α⊃where␈α⊂it␈α⊂is;␈α⊂we␈α⊃have␈α⊂an
␈↓ ↓H␈↓understanding␈αof␈αthe␈αpurpose␈αand␈αintent␈αof␈α␈↓αread␈↓;␈αonly␈αafter␈αthe␈αbasic␈αalgorithm␈αis␈αwell␈αunderstood
␈↓ ↓H␈↓should␈α∞we␈α∞attempt␈α
to␈α∞be␈α∞clever␈α
and␈α∞efficient.␈α∞ First␈α
we␈α∞describe␈α∞the␈α
basic␈α∞ideas␈α∞of␈α∞the␈α
algorithm,
␈↓ ↓H␈↓then we give the algorithm.
␈↓ ↓H␈↓The␈α∪main␈α∪idea␈α∩in␈α∪the␈α∪algorithm␈α∪is␈α∩the␈α∪realization␈α∪that␈α∪we␈α∩really␈α∪can␈α∪determine␈α∪the␈α∩storage
␈↓ ↓H␈↓requirements␈α∂for␈α∞a␈α∂complex␈α∂S-expr␈α∞or␈α∂list␈α∂structure␈α∞as␈α∂we␈α∞read␈α∂it␈α∂in.␈α∞ For␈α∂example␈α∂consider␈α∞the
␈↓ ↓H␈↓input␈α∀string␈α∪"␈↓α(A (B C) D)␈↓".␈α∀As␈α∀we␈α∪start␈α∀our␈α∪left-to-right␈α∀scan␈α∀of␈α∪the␈α∀input␈α∪we␈α∀see␈α∀"␈↓α(␈↓".␈α∪This
␈↓ ↓H␈↓immediately␈αtells␈αus␈αthat␈αwe␈αneed␈αat␈αleast␈αone␈α
␈↓αcons␈↓.␈α We␈αread␈α"␈↓αA␈↓";␈αthat␈αtells␈αus␈αwhat␈αthe␈α␈↓αcar␈↓␈α
of␈αthe
␈↓ ↓H␈↓expression␈αis.␈αNotice␈αthat␈αwe␈αdon't␈αyet␈αknow␈αwhether␈αthe␈αexpression␈αis␈α"dotted"␈αor␈α"listed",␈α
but␈αthe
␈↓ ↓H␈↓storage␈αrequirements␈αwill␈αbe␈αthe␈αsame.␈αOn␈αreading␈αthe␈αnext␈αopen␈αparenthesis␈αwe␈αknow␈αwe␈αneed␈αto
␈↓ ↓H␈↓add␈αa␈αnew␈αlevel␈αin␈αthe␈αdeveloping␈αrepresentation.␈αThe␈α"␈↓αB␈↓"␈αand␈α"␈↓αC␈↓"␈αadd␈αelements␈αto␈αthat␈αlevel,␈αand
␈↓ ↓H␈↓the␈α⊂closing␈α⊂parenthesis␈α∂finishes␈α⊂it␈α⊂off.␈α⊂The␈α∂closing␈α⊂parenthesis␈α⊂also␈α∂should␈α⊂signal␈α⊂our␈α⊂parser␈α∂to
␈↓ ↓H␈↓return␈αto␈αthe␈αprior␈αlevel␈αand␈αcontinue␈αscanning␈αthe␈αinput.␈αThe␈α"␈↓αD␈↓"␈αgoes␈αon␈αthat␈αlevel␈αand␈αthe␈αfinal
␈↓ ↓H␈↓closing␈αparenthesis␈αcompletes␈αthe␈αinput.␈α All␈αthis␈αis␈αold␈αbut␈αthe␈αdifference␈αnow␈αis␈αthat␈αwe␈αdon't␈αuse
␈↓ ↓H␈↓recursion␈αor␈α
an␈αexplicit␈α
stack␈αto␈α
keep␈αtrack␈α
of␈αwhere␈α
we␈αare.␈α
We␈αkeep␈α
a␈αthread␈α
in␈αthe␈α
␈↓αcdr␈↓-part␈αof
␈↓ ↓H␈↓the␈α∂last␈α∂cell␈α∞on␈α∂every␈α∂level.␈α∂When␈α∞we␈α∂go␈α∂down␈α∂a␈α∞level␈α∂we␈α∂manufacture␈α∂a␈α∞new␈α∂cell␈α∂with␈α∂the␈α∞␈↓αcdr␈↓
␈↓ ↓H␈↓pointing␈α⊂to␈α⊂the␈α∂cell␈α⊂we␈α⊂just␈α∂came␈α⊂from␈α⊂in␈α∂the␈α⊂previous␈α⊂level;␈α∂this␈α⊂happens␈α⊂when␈α∂we␈α⊂see␈α⊂a␈α∂left
␈↓ ↓H␈↓parenthesis.␈α
We␈α
go␈α
up␈α
a␈α∞level␈α
when␈α
we␈α
see␈α
a␈α
right␈α∞parenthesis;␈α
that␈α
is␈α
done␈α
by␈α
following␈α∞up␈α
the
␈↓ ↓H␈↓thread in the current level, after doing appropriate cleanup.
␈↓ ↓H␈↓There are three basic states in the reader:
␈↓ ↓H␈↓␈↓ α_␈↓↓1.␈↓␈αThe␈αnext␈αinput␈αshould␈αgo␈αinto␈αthe␈α␈↓αcar␈↓-part␈αof␈αthe␈αcurrent␈αcell.␈α This␈αstate␈αis␈αentered
␈↓ ↓H␈↓␈↓ α_when we go down a level. It is labeled ␈↓αhead␈↓ in the following program.
␈↓ ↓H␈↓␈↓ α_␈↓↓2.␈↓␈α⊂The␈α⊃next␈α⊂input␈α⊃should␈α⊂go␈α⊃on␈α⊂the␈α⊂current␈α⊃level.␈α⊂This␈α⊃is␈α⊂the␈α⊃typical␈α⊂state␈α⊃in␈α⊂the
␈↓ ↓H␈↓␈↓ α_building␈αof␈αa␈αlist-input.␈αHere␈αwe␈αadd␈αa␈αnew␈αcell␈αin␈αthe␈αcurrent␈αlevel␈αand␈αput␈αthe␈αinput
␈↓ ↓H␈↓␈↓ α_in the ␈↓αcar␈↓-part of that cell; then stay in this state. This state corresponds to label ␈↓αtail␈↓.
␈↓ ↓H␈↓␈↓ α_␈↓↓3.␈↓␈αThe␈αother␈αmain␈αstate␈αoccurs␈αon␈αreading␈αa␈αdot␈αwhen␈αin␈α␈↓αtail␈↓-state␈↓π 232␈↓.␈αIn␈α
dot-state␈αwe
␈↓ ↓H␈↓␈↓ α_check␈αthe␈αnext␈α
input;␈αif␈αit's␈αan␈α
atom␈αwe␈αstuff␈αit␈α
on␈αthe␈αthread␈αand␈α
go␈αup.␈αIf␈αit's␈α
a␈αleft
␈↓ ↓H␈↓␈↓ α_parenthesis we add a new cell and go down.
␈↓ ↓H␈↓There␈αare␈α
some␈αanomalies␈α
in␈αthe␈α
algorithm␈αdue␈α
to␈αthe␈α
desire␈αto␈α
recognize␈αboth␈α
S-expr␈αnotation␈α
and
␈↓ ↓H␈↓list-notation.␈αThe␈αmain␈αmalefactor␈α
is␈αa␈αcount␈αof␈αparenthesis;␈α
it␈αincrements␈αfor␈αleft␈α
parentheses␈αand
␈↓ ↓H␈↓decrements␈αfor␈α
right␈αparentheses.␈α
A␈αlegal␈α
input␈αhas␈αbeen␈α
recognized␈αwhen␈α
we␈αare␈α
back␈αat␈α
the␈αtop
␈↓ ↓H␈↓level and the count is zero.
␈↓ ↓H␈↓The␈α⊂final␈α⊂difference␈α∂between␈α⊂the␈α⊂old␈α∂parser␈α⊂and␈α⊂the␈α∂new␈α⊂one␈α⊂involves␈α∂the␈α⊂scanner,␈α⊂␈↓αratom␈↓.␈α∂We
␈↓ ↓H␈↓assume␈αa␈αnew␈α␈↓αratom␈↓␈αwhich␈α
reads␈α␈↓α()␈↓␈αand␈αreturns␈α␈↓αNIL␈↓.␈αThis␈α
is␈αnot␈αtoo␈αstrenuous␈αan␈α
assumption.␈αIf
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 232␈↓ dots seen in any other context are errors
␈↓ ↓H␈↓␈↓↓7.10␈↓ λaA Non-recursive ␈↓αread␈↓↓ 371␈↓α
␈↓ ↓H␈↓the␈α∞scanner␈α∞sees␈α
an␈α∞open␈α∞parenthesis,␈α∞it␈α
looks␈α∞ahead␈α∞to␈α∞the␈α
next␈α∞meaningful␈α∞character␈↓π 233␈↓.␈α∞If␈α
the
␈↓ ↓H␈↓character␈α
is␈α
a␈α∞closing␈α
parenthesis,␈α
it␈α∞takes␈α
it;␈α
if␈α∞the␈α
character␈α
is␈α
not,␈α∞it␈α
is␈α
left␈α∞for␈α
the␈α
next␈α∞call␈α
on
␈↓ ↓H␈↓␈↓αratom␈↓␈α∀and␈α∀␈↓αratom␈↓␈α∀returns␈α∀with␈α∀an␈α∀indication␈α∪that␈α∀it␈α∀has␈α∀seen␈α∀a␈α∀left␈α∀parenthesis.␈α∀ With␈α∪this
␈↓ ↓H␈↓introduction, here is the new ␈↓αread␈↓:
␈↓ ↓H␈↓αread <= λ[[]prog[[j;cp;count;top;temp]
␈↓ ↓H␈↓α␈↓ α_count←init[]; cp←count; top←cp;
␈↓ ↓H␈↓αhead␈↓ α_j←ratom[];
␈↓ ↓H␈↓α␈↓ α_[or[is_dot[j];is_rpar[j]] → err[];
␈↓ ↓H␈↓α␈↓ α_ is_lpar[j] →␈↓ β8incr[count];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8cp←down[cp];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8go[head];
␈↓ ↓H␈↓α␈↓ α_ atom[j] → stuff[cp;j]; go[ckend]];
␈↓ ↓H␈↓αtail␈↓ α_j←ratom[];
␈↓ ↓H␈↓α␈↓ α_[atom[j] → cp←insert_move[cp;j]; go[ckend];
␈↓ ↓H␈↓α␈↓ α_ is_rpar[j] →␈↓ β8decr[count];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8[eq[top;cp] → go[ck1];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8 ␈↓
t␈↓α → cp←stuff_up[cp;NIL]; go[ckend]];
␈↓ ↓H␈↓α␈↓ α_is_lpar[j] →␈↓ β8incr[count];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8cp←down[insert_move[cp;NIL]];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8go[head];
␈↓ ↓H␈↓α␈↓ α_is_dot[j] →␈↓ β8j←ratom[];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8[or[is_dot[j];is_rpar[j]] → err[];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8 is_lpar[j] →␈↓ ∧hincr[count];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8␈↓ ∧hcp←insert_move[cp;NIL];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8␈↓ ∧hgo[head];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8 atom[j] →␈↓ ∧hcp←stuff_up[cp;j];
␈↓ ↓H␈↓α␈↓ α_␈↓ β8␈↓ ∧hgo[ckend]]]; ␈↓π 234␈↓α
␈↓ ↓H␈↓αckend␈↓ α_[eq[cp;top] → go[ck1];
␈↓ ↓H␈↓α␈↓ α_ ␈↓
t␈↓α → go[tail]];
␈↓ ↓H␈↓αck1␈↓ α_temp← cnt[top];
␈↓ ↓H␈↓αend2␈↓ α_[zerop[temp] → return[exp[top]];
␈↓ ↓H␈↓α␈↓ α_j←ratom[];
␈↓ ↓H␈↓α␈↓ α_[is_rpar[j] → temp←sub1[temp]; go[end2];
␈↓ ↓H␈↓α␈↓ α_ ␈↓
t␈↓α → err[] ]]]
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 233␈↓ ignoring spaces and the like
␈↓ ↓H␈↓α␈↓π 234␈↓α ␈↓This ␈↓αgo␈↓ is superfluous, but makes the flow more apparent.
␈↓ ↓H␈↓␈↓↓372 Storage Structures and Efficiency␈↓ )7.10␈↓
␈↓ ↓H␈↓αinit <= λ[[] cons[NIL;0]]
␈↓ ↓H␈↓αstuff <= λ[[x;y] rplaca[x;y]]
␈↓ ↓H␈↓αincr <= λ[[z] rplacd[z;add1[cdr[z]]]]
␈↓ ↓H␈↓αinsert_move <= λ[[cp;val] rplacd[cp;cons[val;cdr[cp]]]; cdr[cp]]
␈↓ ↓H␈↓αdown <= λ[[cp] rplaca[cp;cons[NIL;cp]];car[cp]]
␈↓ ↓H␈↓αstuff_up <= λ[[cp;j] prog[[temp]
␈↓ ↓H␈↓α␈↓ ∧_temp ← cdr[cp];
␈↓ ↓H␈↓α␈↓ ∧_rplacd[cp;j];
␈↓ ↓H␈↓α␈↓ ∧_return[temp]]]
␈↓ ↓H␈↓αcnt <= λ[[x] cdr[x]]
␈↓ ↓H␈↓αexp <= λ[[x] car[x]]
␈↓ ↓H␈↓The␈αdevelopment␈αand␈αunderstanding␈αof␈αthis␈αalgorithm␈αrequired␈αmost␈αof␈αwhat␈αwe␈αhave␈αcovered␈αin
␈↓ ↓H␈↓the␈αcourse.␈αWe␈αused␈αour␈αknowledge␈αof␈αthe␈αparser,␈α␈↓αread␈↓;␈αwe␈αused␈αour␈αfamiliarity␈αwith␈αS-exprs␈α
stored
␈↓ ↓H␈↓as␈αlinked-lists;␈α
we␈αhave␈αto␈α
understand␈αthe␈α
run-time␈αcontrol␈αof␈α
recursive␈αcalling␈α
sequences;␈αwe␈αhad␈α
to
␈↓ ↓H␈↓understand␈αpointer␈α
manipulation;␈αwe␈α
have␈αto␈αunderstand␈α
pointer␈αmodification;␈α
and␈αfinally␈αwe␈α
have
␈↓ ↓H␈↓to␈αbe␈αwickedly␈αclever.␈α With␈αthat␈αunderstanding␈αwe␈αwere␈αable␈αto␈αapply␈αthreading␈αat␈αa␈αlevel␈αhigher
␈↓ ↓H␈↓than a "once-only" trick.
␈↓ ↓H␈↓␈↓ ε↔␈↓↓Problem␈↓
␈↓ ↓H␈↓␈↓↓1.␈↓ Write a version of ␈↓αread␈↓ which uses an explicit stack to remember where it is in the parse.
␈↓ ↓H␈↓␈↓↓7.11␈↓ πCMore Applications of Threading 373␈↓
␈↓ ↓H␈↓␈↓ ∧T␈↓↓7.11 More Applications of Threading␈↓
␈↓ ↓H␈↓␈↓ ∧2␈↓↓A link-bending garbage collector for LISP␈↓
␈↓ ↓H␈↓The␈αuse␈αof␈α
a␈αstack␈αis␈α
one␈αof␈αthe␈α
difficulties␈αassociated␈αwith␈α
garbage␈αcollection.␈αGarbage␈αcollection␈α
is
␈↓ ↓H␈↓invoked␈α
when␈α
available␈αspace␈α
has␈α
become␈α
exhausted,␈αbut␈α
here␈α
we␈α
are,␈αasking␈α
for␈α
␈↓↓more␈↓␈α
space␈αto␈α
use
␈↓ ↓H␈↓for␈α⊃stacking.␈α⊃ The␈α⊃usual␈α⊃solution␈α⊃is␈α⊃to␈α⊃allocate␈α⊂a␈α⊃separate␈α⊃area␈α⊃for␈α⊃stack␈α⊃storage.␈α⊃This␈α⊃has␈α⊂its
␈↓ ↓H␈↓drawbacks.␈αIf␈αwe␈αdon't␈αallocate␈αenough␈αstack␈αspace,␈α
i.e.,␈αif␈αthe␈αdepth␈αof␈αa␈αpiece␈αof␈αstructure␈α
becomes
␈↓ ↓H␈↓too␈αgreat,␈αthen␈αthe␈αmarker␈αwill␈αfail.␈α The␈αamount␈αof␈αstack␈αspace␈αcan␈αbecome␈αlarge;␈α
proportional␈αto
␈↓ ↓H␈↓the␈α∂depth␈α∞of␈α∂a␈α∞list.␈α∂ We␈α∞can␈α∂apply␈α∞threading␈α∂here,␈α∞modifying␈α∂the␈α∞structure␈α∂as␈α∞we␈α∂traverse␈α∂it;␈α∞as
␈↓ ↓H␈↓usual␈α
the␈α
threads␈α
will␈α
be␈α
used␈α
as␈α
control␈α
information.␈α
As␈α
we␈α
finish␈α
marking␈α
a␈α
branch␈α∞we␈α
restore
␈↓ ↓H␈↓the␈αstructure␈αto␈αits␈αoriginal␈αtopology.␈α Several␈αversions␈αof␈αsuch␈αthreaded␈αcollectors␈αare␈αavailable;␈αsee
␈↓ ↓H␈↓[Chr 68]␈α↔for␈α⊗a␈α↔version␈α↔written␈α⊗in␈α↔AMBIT/G;␈α⊗a␈α↔more␈α↔traditional␈α⊗description␈α↔is␈α↔found␈α⊗in
␈↓ ↓H␈↓[Sch 67]␈↓π 235␈↓; and see [Knu 68] for several alternatives.
␈↓ ↓H␈↓␈↓ ¬"␈↓↓Binding Implementations␈↓
␈↓ ↓H␈↓Threading␈α∞can␈α
be␈α∞used␈α∞in␈α
the␈α∞shallow␈α
binder␈α∞of␈α∞Section 5.20␈α
to␈α∞remember␈α
the␈α∞path␈α∞through␈α
the
␈↓ ↓H␈↓environment␈α∞tree ([Urm 76]).␈α
We␈α∞thread␈α
from␈α∞E␈↓βbind␈↓␈α
to␈α∞E␈↓βinter␈↓␈α
when␈α∞we␈α
are␈α∞looking␈α
for␈α∞E␈↓βinter␈↓.␈α
This
␈↓ ↓H␈↓consists␈α
of␈α
reversing␈α
the␈α
access␈α
links␈α
as␈α
we␈α
proceed␈α
towards␈α
E␈↓βinter␈↓.␈α
Then,␈α
as␈α
we␈α
swap␈α
back␈αthe␈α
value
␈↓ ↓H␈↓cells, we will unthread from E␈↓βinter␈↓ to E␈↓βbind␈↓.
␈↓ ↓H␈↓␈↓ ∧[␈↓↓7.12 Storage Management and LISP␈↓
␈↓ ↓H␈↓There␈α
are␈α
two␈α
basic␈α
areas␈α
of␈α
LISP␈αwhich␈α
require␈α
attention:␈α
the␈α
implementation␈α
of␈α
data␈αstuctures,
␈↓ ↓H␈↓and the implementation of the LISP machine. We will discuss applications in that order.
␈↓ ↓H␈↓LISP's␈α∂most␈α∂general␈α∂data␈α∂object␈α∂is␈α∂a␈α∂dotted␈α∞pair;␈α∂however␈α∂we␈α∂frequently␈α∂are␈α∂found␈α∂to␈α∂be␈α∞using
␈↓ ↓H␈↓dotted␈α⊂pairs␈α⊂to␈α⊂represent␈α⊂more␈α⊂structured␈α∂objects.␈α⊂ For␈α⊂example,␈α⊂many␈α⊂common␈α⊂LISP␈α∂programs
␈↓ ↓H␈↓involve␈α
list-operations␈α
on␈α
list␈αrepresentations.␈α
But␈α
lists,␈α
we␈αknow,␈α
are␈α
representations␈α
of␈αsequences.
␈↓ ↓H␈↓From␈α
Section 7.2␈αwe␈α
now␈αalso␈α
know␈αthat␈α
arrays␈αare␈α
efficient␈αrepresentations␈α
of␈α
sequences.␈α Indeed
␈↓ ↓H␈↓array␈αrepresentations␈αare␈αtypically␈αmore␈αefficient␈αthan␈αthe␈αgeneral␈αLISP␈αlinked-list.␈α We␈αwould␈αlike
␈↓ ↓H␈↓to capitalize on this more efficient representation without jeopardizing the LISP operations.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 235␈↓ The correctness of [Sch 67] has been proved by de Roever.
␈↓ ↓H␈↓␈↓↓374 Storage Structures and Efficiency␈↓ )7.12␈↓
␈↓ ↓H␈↓An␈α
analysis␈α
of␈α
the␈α
LISP␈α
operations␈α
shows␈α
that␈α
we␈α
have␈α
to␈α
be␈α
able␈α
to␈α
␈↓↓share␈↓␈α
substructures,␈α
and␈α
if
␈↓ ↓H␈↓using␈α␈↓αrplaca␈↓␈αor␈α␈↓αrplacd␈↓,␈αwe␈αhave␈αto␈αbe␈αable␈αto␈α␈↓↓modify␈↓␈αexisting␈αstructures.␈αAny␈αproposed␈αeconomies
␈↓ ↓H␈↓in␈α
storage␈α
layout␈α
must␈αtake␈α
cognizance␈α
of␈α
these␈αfacts.␈α
Fortunately␈α
these␈α
requirements␈αare␈α
compatible.
␈↓ ↓H␈↓Consider the typical representation of the sequence:
␈↓ ↓H␈↓α␈↓ ¬-(LAMBDA (X) (F X Y))
␈↓"␈↓ ↓H␈↓
⊂ααααααααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
~ LAMBDA ~ #αβαα→~ # ~ #αβα→~ # ~≤'~
␈↓"␈↓ ↓H␈↓
%αααααααα∀ααα$ %αβα∀ααα$ %αβα∀αα$
␈↓"␈↓ ↓H␈↓
~ ↓
␈↓"␈↓ ↓H␈↓
⊂αααααααααα$ ⊂αααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
↓ ~ F ~ #αβ→~ X ~ #αβ→~ Y ~≤'~
␈↓"␈↓ ↓H␈↓
⊂αααπαα⊃ %ααα∀ααα$ %ααα∀ααα$ %ααα∀αα$
␈↓"␈↓ ↓H␈↓
~ X ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀αα$
␈↓ ↓H␈↓This␈αtakes␈αseven␈αwords.␈αThe␈α␈↓αcar␈↓-part␈αof␈αeach␈αcell␈αcontains␈αthe␈αinformation;␈αthe␈α␈↓αcdr␈↓-part␈αtells␈αwhere
␈↓ ↓H␈↓the␈α
rest␈α
of␈αthe␈α
expression␈α
is␈α
to␈αbe␈α
found.␈α
That␈αis,␈α
we␈α
have␈α
dedicated␈α14␈α
half-words␈α
to␈αrepresent␈α
the
␈↓ ↓H␈↓structure;␈α
only␈α
seven␈α
of␈α∞which␈α
contain␈α
the␈α
actual␈α
information␈α∞we␈α
wish␈α
to␈α
store.␈α
Using␈α∞some␈α
extra
␈↓ ↓H␈↓encoding we can carry the same information in seven␈↓π 236␈↓ cells.
␈↓"␈↓ ↓H␈↓
⊂ααααααααα⊃
␈↓"␈↓ ↓H␈↓
~↓ LAMBDA ~
␈↓"␈↓ ↓H␈↓
εαααααααααλ ⊂αααααααα⊃
␈↓"␈↓ ↓H␈↓
~↓ #αβαααα→~/ X ~
␈↓"␈↓ ↓H␈↓
εαααααααααλ %αααααααα$
␈↓"␈↓ ↓H␈↓
~/ #αβα⊃
␈↓"␈↓ ↓H␈↓
%ααααααααα$ ↓ ⊂αααααααα⊃
␈↓"␈↓ ↓H␈↓
%αα→~↓ F ~
␈↓"␈↓ ↓H␈↓
εααααααααλ
␈↓"␈↓ ↓H␈↓
~↓ X ~
␈↓"␈↓ ↓H␈↓
εααααααααλ
␈↓"␈↓ ↓H␈↓
~/ Y ~
␈↓"␈↓ ↓H␈↓
%αααααααα$
␈↓ ↓H␈↓The␈α⊗intent␈α∃of␈α⊗the␈α∃special␈α⊗characters␈α∃is␈α⊗to␈α∃encode␈α⊗information␈α∃about␈α⊗the␈α∃␈↓↓next␈↓␈α⊗cell␈α⊗in␈α∃the
␈↓ ↓H␈↓representation.␈α
It␈αthus␈α
is␈α
called␈α␈↓↓␈↓αcdr␈↓↓-coding␈↓.␈α
The␈α
␈↓
↓␈↓␈αmeans␈α
the␈αnext␈α
cell␈α
␈↓↓is␈↓␈αthe␈α
␈↓αcdr␈↓;␈α
␈↓
/␈↓␈αmeans␈α
the␈α␈↓αcdr␈↓␈α
is
␈↓ ↓H␈↓␈↓αNIL␈↓.
␈↓ ↓H␈↓The␈αtypical␈αLISP␈αcell␈αis␈αa␈α
third␈αvariety␈αof␈α␈↓αcdr␈↓-coding:␈αthe␈αcode␈α␈↓
→␈↓␈α
says␈αthe␈αnext␈αcell␈αis␈αa␈α
pointer␈αto
␈↓ ↓H␈↓the␈α
␈↓αcdr␈↓.␈α
With␈α
that,␈α
we␈α
introduce␈α
the␈α
final␈α
code:␈α␈↓
*␈↓␈α
means␈α
this␈α
cell␈α
is␈α
the␈α
␈↓αcdr␈↓-half␈α
of␈α
a␈α
LISP␈αword.
␈↓ ↓H␈↓Thus ␈↓α(A B)␈↓ could be expressed in any of the following forms:
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 236␈↓ slightly larger
␈↓ ↓H␈↓␈↓↓7.12␈↓ πSStorage Management and LISP 375␈↓
␈↓"␈↓ ↓H␈↓
⊂ααααα⊃ ⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
~↓ A ~ ~→ A ~
␈↓"␈↓ ↓H␈↓
εαααααλ εαααααλ ⊂ααααα⊃
␈↓"␈↓ ↓H␈↓
~/ B ~ ~* #αβααα→~/ B ~
␈↓"␈↓ ↓H␈↓
%ααααα$ %ααααα$ %ααααα$
␈↓"␈↓ ↓H␈↓
⊂ααααα⊃ ⊂αααααπααααα⊃ ⊂αααααπααααα⊃
␈↓"␈↓ ↓H␈↓
~→ A ~ ~ A ~ #αβααα→~ B ~ ≤' ~
␈↓"␈↓ ↓H␈↓
εαααααλ ⊂ααααα⊃ %ααααα∀ααααα$ %ααααα∀ααααα$
␈↓"␈↓ ↓H␈↓
~* #αβαα→~→ B ~
␈↓"␈↓ ↓H␈↓
%ααααα$ εαααααλ
␈↓"␈↓ ↓H␈↓
~* NIL~
␈↓"␈↓ ↓H␈↓
%ααααα$
␈↓ ↓H␈↓However␈αthis␈α
encoding␈αscheme␈αis␈α
not␈αsufficient␈αas␈α
it␈αstands.␈αConsider␈α
the␈αfollowing␈αexample:␈α
Given
␈↓ ↓H␈↓internal pointers ␈↓αx␈↓ and ␈↓αz␈↓ into:
␈↓"␈↓ ↓H␈↓
x z
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
↓ ⊂αααπααα⊃ ↓ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%αα→~ F ~ #αβαα∀αα→~ X ~ #αβαα→~ Y ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓and␈α⊂assume␈α⊃we␈α⊂wish␈α⊃to␈α⊂perform␈α⊂␈↓αrplacd[x;(A B C)]␈↓.␈α⊃ In␈α⊂our␈α⊃standard␈α⊂implementation␈α⊃we␈α⊂would
␈↓ ↓H␈↓arrive at:
␈↓"␈↓ ↓H␈↓
x z
␈↓"␈↓ ↓H␈↓
~ ~
␈↓"␈↓ ↓H␈↓
↓ ⊂αααπααα⊃ ↓ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%αα→~ F ~ # ~ %αα→~ X ~ #αβαα→~ Y ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀αβα$ %ααα∀ααα$ %ααα∀αα$
␈↓"␈↓ ↓H␈↓
↓
␈↓"␈↓ ↓H␈↓
~ ⊂αααπααα⊃ ⊂αααπααα⊃ ⊂αααπαα⊃
␈↓"␈↓ ↓H␈↓
%→~ A ~ #αβααααα→~ B ~ #αβαα→~ C ~≤'~
␈↓"␈↓ ↓H␈↓
%ααα∀ααα$ %ααα∀ααα$ %ααα∀αα$
␈↓ ↓H␈↓But␈α∞if␈α∞we␈α∞assume␈α
␈↓α(F␈α∞X␈α∞Y)␈↓␈α∞is␈α∞represented␈α
in␈α∞its␈α∞compact␈α∞form␈α
we␈α∞have␈α∞some␈α∞troubles.␈α∞ We␈α
can't
␈↓ ↓H␈↓replace the cell:
␈↓"␈↓ ↓H␈↓
⊂ααααα⊃ ⊂αααααα⊃
␈↓"␈↓ ↓H␈↓
~↓ X ~ by ~* #αβ→ to ␈↓α(A B C)␈↓
␈↓"␈↓ ↓H␈↓
%ααααα$ %αααααα$
␈↓ ↓H␈↓since␈α⊂␈↓αz␈↓␈α⊂would␈α∂get␈α⊂justifiably␈α⊂upset.␈α∂What␈α⊂we␈α⊂will␈α∂do␈α⊂is␈α⊂use␈α∂the␈α⊂forwarding␈α⊂address␈α⊂scheme␈α∂we
␈↓ ↓H␈↓introduced␈αon␈αpage 353␈αin␈αthe␈αcompacting␈α
garbage␈αcollector.␈α We␈αput␈αa␈αforwarding␈αaddress␈α
in␈αthe
␈↓ ↓H␈↓cell␈α
referenced␈α
by␈α␈↓αx␈↓;␈α
then␈α
allocate␈αa␈α
new␈α
pair␈αof␈α
half-cells,␈α
putting␈α␈↓αF␈↓␈α
in␈α
the␈αfirst␈α
and␈α
a␈α
pointer␈αto
␈↓ ↓H␈↓␈↓α(A B C)␈↓ in the second.
␈↓ ↓H␈↓␈↓↓376 Storage Structures and Efficiency␈↓ )7.12␈↓
␈↓"␈↓ ↓H␈↓
x ⊂ααααααααα⊃ ⊂αααααααα⊃ ⊂αααααααα⊃
␈↓"␈↓ ↓H␈↓
%→αα→~i #αβαααα→~↓ F ~ ⊂→αα→~↓ A ~
␈↓"␈↓ ↓H␈↓
εαααααααααλ εααααααααλ ↑ εααααααααλ
␈↓"␈↓ ↓H␈↓
z →α→~↓ X ~ ~* #αβα$ ~↓ B ~
␈↓"␈↓ ↓H␈↓
εαααααααααλ %αααααααα$ εααααααααλ
␈↓"␈↓ ↓H␈↓
~/ Y ~ ~/ C ~
␈↓"␈↓ ↓H␈↓
%ααααααααα$ %αααααααα$
␈↓ ↓H␈↓These␈αforwarding␈αaddresses␈αare␈αan␈αinstance␈αof␈α␈↓↓invisible␈αpointers␈↓␈αproposed␈αby␈αR.␈αGreenblatt␈αin␈α
his
␈↓ ↓H␈↓LISP␈α⊃machine;␈α⊂he␈α⊃has␈α⊂also␈α⊃proposed␈α⊂implementing␈α⊃␈↓αcdr␈↓-coding␈α⊂in␈α⊃hardware.␈α⊃ Between␈α⊂invisible
␈↓ ↓H␈↓pointers␈α⊂and␈α⊂␈↓αcdr␈↓-coding,␈α⊂we␈α∂␈↓↓can␈↓␈α⊂effect␈α⊂all␈α⊂LISP␈α∂operations␈α⊂using␈α⊂this␈α⊂potentially␈α⊂more␈α∂compact
␈↓ ↓H␈↓representation.
␈↓ ↓H␈↓We␈α⊂must␈α∂be␈α⊂able␈α∂to␈α⊂maintain␈α⊂that␈α∂compact␈α⊂representation␈α∂while␈α⊂the␈α∂program␈α⊂is␈α⊂running.␈α∂That
␈↓ ↓H␈↓requires␈αmore␈αcare␈αin␈αthe␈αmanagement␈αof␈αstorage.␈α We␈αcannot␈αsimply␈αgarbage␈αcollect␈αand␈αfragment
␈↓ ↓H␈↓space;␈α
we␈α
cannot␈α
use␈α
the␈α
simple␈α
compacting␈αgarbage␈α
collector␈α
of␈α
Section 7.4␈α
since␈α
it␈α
does␈αnot␈α
attempt
␈↓ ↓H␈↓to␈α∀maintain␈α∀the␈α∀compact␈α∀representation.␈α∪Several␈α∀algorithms␈α∀with␈α∀the␈α∀desired␈α∀properties␈α∪exist
␈↓ ↓H␈↓([Che 70],␈α⊂[Cla 76]).␈α⊂ One␈α⊂feature␈α⊂of␈α⊂this␈α⊂data␈α⊂representation␈α⊂is␈α⊂its␈α⊂use␈α⊂of␈α⊂variable-sized␈α∂linked
␈↓ ↓H␈↓blocks␈αof␈αsequential␈αstorage.␈αThe␈αmanagement␈αof␈αthese␈αstorage␈αblocks␈αis␈αmore␈αcomplex␈αthan␈αthat␈αof
␈↓ ↓H␈↓simple␈α∂dotted-pairs,␈α⊂but␈α∂the␈α∂additional␈α⊂overhead␈α∂may␈α∂be␈α⊂acceptable␈α∂if␈α∂it␈α⊂gives␈α∂better␈α⊂locality␈α∂of
␈↓ ↓H␈↓reference and faster access to list elements␈↓π 237␈↓.
␈↓ ↓H␈↓There␈αis␈αless␈αconflict␈αabout␈αthe␈αuse␈αof␈αmore␈αcomplex␈αstorage␈αmanagement␈αtechniques␈αin␈αthe␈αarea␈αof
␈↓ ↓H␈↓LISP's␈α∞dynamic␈α
implementation.␈α∞ The␈α
original␈α∞versions␈α
of␈α∞LISP 1.5␈α
used␈α∞dotted␈α
pair␈α∞structure␈α
to
␈↓ ↓H␈↓represent␈α~the␈α≠access␈α~environments␈↓π 238␈↓.␈α~This␈α≠generality␈α~allowed␈α~a␈α≠correct␈α~solution␈α≠to␈α~the
␈↓ ↓H␈↓implementation␈α
of␈α
␈↓αfunction␈↓,␈α
but␈αexperience␈α
with␈α
LISP␈α
implementations␈αhas␈α
shown␈α
that␈α
it␈α
is␈αquite
␈↓ ↓H␈↓expensive␈α∃to␈α∃maintain␈α∃this␈α∀generality␈α∃when␈α∃most␈α∃applications␈α∀are␈α∃of␈α∃a␈α∃less␈α∃general␈α∀nature.
␈↓ ↓H␈↓Implementation␈α∪techniques,␈α∀patterned␈α∪after␈α∀our␈α∪Weizenbaum␈α∀diagrams,␈α∪allow␈α∀some␈α∪economies
␈↓ ↓H␈↓without␈α
loss␈αof␈α
generality.␈α Again,␈α
storage␈αwould␈α
be␈α
allocated␈αin␈α
sequential␈αblocks;␈α
each␈αblock␈α
would
␈↓ ↓H␈↓be␈αof␈αsize␈αsufficient␈αto␈αhold␈αthe␈αrepresentation␈αof␈αthe␈αname-value␈αentries␈αalong␈αwith␈αthe␈αadditional
␈↓ ↓H␈↓areas␈αto␈αlink␈αthe␈αblock␈αto␈αthe␈α
environment.␈α The␈αstorage␈αblocks␈αneed␈αnot␈αbe␈α
allocated␈αsequentially;
␈↓ ↓H␈↓indeed,␈αin␈αthe␈αgeneral␈αcase␈αblocks␈α
cannot␈αbe␈αallocated␈αsequentially.␈αThe␈αde-allocation␈α
problems␈αare
␈↓ ↓H␈↓somewhat␈α∂different␈α∂from␈α∂those␈α⊂experienced␈α∂by␈α∂data␈α∂structure␈α∂representations.␈α⊂ The␈α∂environment
␈↓ ↓H␈↓structures␈α
are␈α
much␈α
more␈α
"well-behaved"␈αthan␈α
general␈α
list-strucuture.␈α
Therefore␈α
an␈α"environment
␈↓ ↓H␈↓garbage collector" may not be needed.
␈↓ ↓H␈↓The␈α∪most␈α∪general␈α∪techniques␈α∪for␈α∪management␈α∪of␈α∪LISP's␈α∪dynamic␈α∪environment␈α∪are␈α∪based␈α∩on
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 237␈↓␈α∂Notice␈α∞that␈α∂the␈α∞␈↓αcdr␈↓-coded␈α∂representation␈α∂of␈α∞␈↓α(A B)␈↓␈α∂and␈α∞␈↓α(A . B)␈↓␈α∂are␈α∞equally␈α∂expensive.␈α∂In␈α∞the
␈↓ ↓H␈↓typical linked-list representation, ␈↓α(A B)␈↓ requires more space than ␈↓α(A . B)␈↓.
␈↓ ↓H␈↓␈↓π 238␈↓ The control information did use a stack implementation coded in machine language.
␈↓ ↓H␈↓␈↓↓7.12␈↓ πSStorage Management and LISP 377␈↓
␈↓ ↓H␈↓[Bob 73a] and succeeding papers␈↓π 239␈↓.
␈↓ ↓H␈↓At␈α⊃a␈α⊃lower␈α⊃level␈α⊃of␈α⊃implementation,␈α∩LISP␈α⊃has␈α⊃much␈α⊃to␈α⊃say␈α⊃about␈α⊃machine␈α∩organization.␈α⊃The
␈↓ ↓H␈↓implementation␈α∞of␈α∂efficient␈α∞environment␈α∂swapping␈α∞algorithms␈α∂is␈α∞a␈α∂problem␈α∞which␈α∂any␈α∞operating
␈↓ ↓H␈↓system␈α≥must␈α≤face.␈α≥ The␈α≥traditional␈α≤solutions␈α≥impose␈α≤severe␈α≥restrictions␈α≥on␈α≤inter-process
␈↓ ↓H␈↓communications.␈α≠The␈α≠algorithms␈α≠developed␈α≠for␈α~LISP␈α≠show␈α≠promise␈α≠for␈α≠giving␈α~efficient
␈↓ ↓H␈↓implementations of more general scope.
␈↓ ↓H␈↓LISP's␈α
orgainzation␈αof␈α
memory␈α
also␈αhas␈α
lessons␈αfor␈α
machine␈α
architecture.␈αThe␈α
management␈αof␈α
large
␈↓ ↓H␈↓variable␈α⊃sized␈α∩memory␈α⊃spaces␈α∩like␈α⊃[Ste 73]␈α∩or␈α⊃[Wegb 70]␈α∩can␈α⊃be␈α∩supported␈α⊃in␈α∩hardware.␈α⊃The
␈↓ ↓H␈↓allocation␈αand␈αde-allocation␈αof␈αsuch␈αlarge␈αspaces␈αalso␈αrequire␈αcare;␈αLISP␈αimplementors␈αhave␈αbegun
␈↓ ↓H␈↓to address these problems ([Ste 76a], [Bis 74a]).
␈↓ ↓H␈↓Finally,␈α⊃the␈α⊂highly␈α⊃interactive␈α⊂nature␈α⊃of␈α⊃modern␈α⊂LISP␈α⊃programming␈α⊂systems␈α⊃gives␈α⊃direction␈α⊂to
␈↓ ↓H␈↓efforts developing more "reactive" programming systems ([Win 75]).
␈↓ ↓H␈↓␈↓ ¬;␈↓↓7.13 Hash Techniques␈↓
␈↓ ↓H␈↓One␈α∪very␈α∪significant␈α∪problem␈α∩experienced␈α∪by␈α∪a␈α∪LISP␈α∪programmer␈α∩is␈α∪the␈α∪sheer␈α∪size␈α∪of␈α∩data
␈↓ ↓H␈↓structures␈α⊃which␈α∩a␈α⊃large␈α⊃LISP␈α∩program␈α⊃generates.␈α∩ Many␈α⊃LISP␈α⊃projects␈α∩approach␈α⊃10␈↓π7␈↓␈α∩bits␈α⊃of
␈↓ ↓H␈↓program␈α∂and␈α∞data.␈α∂ Several␈α∞techniques␈α∂have␈α∞been␈α∂developed␈α∞to␈α∂help␈α∞shrink␈α∂data␈α∞representation;
␈↓ ↓H␈↓␈↓αcdr␈↓-coding␈α
(Section 7.12)␈αis␈α
one␈α
technique.␈αAnother␈α
technique␈α
stems␈αfrom␈α
the␈α
observation␈αthat␈α
LISP
␈↓ ↓H␈↓tends␈α
to␈α␈↓↓copy␈↓␈α
structures␈αrather␈α
than␈α␈↓↓share␈↓␈α
them.␈αWe␈α
know␈αthat␈α
the␈αsharing␈α
of␈αstructures␈α
must␈αbe
␈↓ ↓H␈↓done␈αwith␈α
great␈αcare␈α
if␈αmodification␈αoperations␈α
like␈α␈↓αrplaca␈↓␈α
and␈α␈↓αrplacd␈↓␈αare␈α
present,␈αbut␈α
sharing␈αof
␈↓ ↓H␈↓structure␈α
can␈α
mean␈α∞a␈α
significant␈α
saving␈α∞in␈α
space.␈α
In␈α
fact,␈α∞the␈α
saving␈α
can␈α∞also␈α
be␈α
reflected␈α∞in␈α
the
␈↓ ↓H␈↓algorithms␈α
which␈α
manipulate␈α
the␈α
structures.␈α
For␈α
example␈α
if␈α
every␈α
list-structure␈α
is␈α
stored␈αuniquely,
␈↓ ↓H␈↓then␈α
the␈α
time␈α
for␈α
the␈α
equality␈α
test␈α
␈↓αequal␈↓␈αis␈α
a␈α
constant␈α
rather␈α
than␈α
being␈α
proportional␈α
to␈α
the␈αdepth␈α
of
␈↓ ↓H␈↓the structure.
␈↓ ↓H␈↓There␈α∞are␈α∞two␈α∞alternatives␈α
for␈α∞maintaining␈α∞unique␈α∞structure:␈α
either␈α∞maintain␈α∞list␈α∞space␈α∞such␈α
that
␈↓ ↓H␈↓unique␈αrepresentations␈αare␈αalways␈αpresent;␈αor␈αsupply␈αan␈αalgorithm␈αwhich␈αwill␈α"uniquize"␈αstructures
␈↓ ↓H␈↓upon␈α
request.␈α
The␈α
first␈α
alternative␈α
is␈α
usually␈α
called␈α
␈↓↓hash␈α
consing␈↓;␈α
the␈α
second␈α
technique␈α
is␈α
called␈α
␈↓↓list
␈↓ ↓H␈↓↓condensation␈↓ ([Lin 73]).␈α∩ A␈α∩condensation␈α∩algorithm␈α∩must␈α∩remove␈α∩all␈α∩duplicated␈α∩structure␈α⊃from
␈↓ ↓H␈↓within␈α∞a␈α∞list.␈α∞Since␈α∞condensation␈α∞is␈α∞a␈α
component␈α∞of␈α∞many␈α∞hashed␈α∞LISP␈α∞implementations,␈α∞we␈α
will
␈↓ ↓H␈↓concentrate our attention on hash consing.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 239␈↓␈α∩There␈α∩is␈α⊃something␈α∩contradictory␈α∩about␈α∩LISP␈α⊃implementor's␈α∩attitudes␈α∩toward␈α∩storage␈α⊃and
␈↓ ↓H␈↓dynamics.␈α∩Much␈α∩effort␈α∩is␈α∩expended␈α∩in␈α∪attempting␈α∩to␈α∩minimize␈α∩the␈α∩overhead␈α∩involved␈α∪in␈α∩the
␈↓ ↓H␈↓dynamic␈α⊃operation␈α∩of␈α⊃LISP;␈α∩it␈α⊃is␈α∩frequently␈α⊃stated␈α∩that␈α⊃the␈α∩user␈α⊃should␈α∩not␈α⊃be␈α∩penalized␈α⊃for
␈↓ ↓H␈↓access/control␈α∞constructs␈α
which␈α∞he␈α
does␈α∞not␈α
use.␈α∞However,␈α
that␈α∞attitude␈α
is␈α∞not␈α
extended␈α∞to␈α
LISP's
␈↓ ↓H␈↓data␈αstructures.␈α
There␈αare␈α
very␈αgenerous␈α
subsets␈αof␈αLISP␈α
applications␈αin␈α
which␈αthe␈α
data␈αstructure
␈↓ ↓H␈↓operations␈αare␈αsuitably␈αwell-behaved,␈αthat␈αstorage␈αreclamation␈αtechniques␈αless␈αgeneral␈αthan␈αgarbage
␈↓ ↓H␈↓collection are applicable. Analysis of this area of LISP should lead to profitable results.
␈↓ ↓H␈↓␈↓↓378 Storage Structures and Efficiency␈↓ )7.13␈↓
␈↓ ↓H␈↓Hash␈α⊃consing␈α⊃is␈α⊃an␈α∩extension␈α⊃of␈α⊃the␈α⊃LISP␈α⊃technique␈α∩for␈α⊃generating␈α⊃unique␈α⊃atoms.␈α∩ Since␈α⊃list
␈↓ ↓H␈↓structure␈α⊃is␈α⊃created␈α⊂only␈α⊃by␈α⊃the␈α⊂␈↓αcons␈↓␈α⊃operation␈↓π 240␈↓,␈α⊃we␈α⊂place␈α⊃the␈α⊃responsibility␈α⊃for␈α⊂maintaining
␈↓ ↓H␈↓unique␈α⊂structure␈α∂on␈α⊂␈↓αcons␈↓.␈α⊂ If␈α∂the␈α⊂result␈α⊂of␈α∂a␈α⊂pending␈α⊂␈↓αcons␈↓␈α∂is␈α⊂already␈α⊂present,␈α∂then␈α⊂we␈α⊂return␈α∂a
␈↓ ↓H␈↓pointer␈α∂to␈α∞that␈α∂structure,␈α∂otherwise␈α∞we␈α∂perform␈α∂the␈α∞␈↓αcons␈↓␈α∂and␈α∂record␈α∞the␈α∂result␈α∂so␈α∞that␈α∂it␈α∂will␈α∞be
␈↓ ↓H␈↓retrieved␈α
if␈α
the␈α
same␈α
␈↓αcons␈↓␈α
happens␈α
again.␈α
The␈α
adjective␈α
"hash"␈α
is␈α
applied␈α
to␈α
this␈α
version␈α
of␈α
␈↓αcons␈↓
␈↓ ↓H␈↓since␈α∩the␈α⊃typical␈α∩implementation␈α⊃uses␈α∩a␈α⊃hashing␈α∩algorithm␈α⊃to␈α∩maintain␈α⊃the␈α∩uniqueness.␈α⊃ Hash
␈↓ ↓H␈↓␈↓αcons␈↓ing␈α⊃imposes␈α⊂restrictions␈α⊃on␈α⊂the␈α⊃programmer's␈α⊃use␈α⊂of␈α⊃list␈α⊂modification␈α⊃operations.␈α⊃If␈α⊂unique
␈↓ ↓H␈↓copies␈α
are␈α
available␈α
severe␈α∞difficulties␈α
result␈α
if␈α
modifications␈α∞are␈α
made.␈α
One␈α
may␈α∞either␈α
disallow
␈↓ ↓H␈↓list␈α
modification,␈α
or␈α
may␈αsupply␈α
additional␈α
operations␈α
to␈αcopy␈α
structure,␈α
modify␈α
it,␈α
and␈α"uniquize"
␈↓ ↓H␈↓the␈α∂result;␈α∂or␈α∂an␈α∞implementation␈α∂may␈α∂supply␈α∂different␈α∞kinds␈α∂of␈α∂structures,␈α∂some␈α∂modifiable,␈α∞and
␈↓ ↓H␈↓some not modifiable.
␈↓ ↓H␈↓A␈α∂hash␈α∂␈↓αcons␈↓␈α∂was␈α∂proposed␈α∂for␈α∂LISP␈α⊂1.75␈α∂on␈α∂the␈α∂IBM M44,␈α∂but␈α∂the␈α∂implementation␈α⊂was␈α∂never
␈↓ ↓H␈↓completed.␈α∂A␈α⊂limited␈α∂version␈α∂of␈α⊂hash␈α∂␈↓αcons␈↓ing␈α∂was␈α⊂implemented␈α∂as␈α∂an␈α⊂extension␈α∂of␈α∂LISP␈α⊂1.6␈α∂at
␈↓ ↓H␈↓Stanford.
␈↓ ↓H␈↓The␈αmost␈αimpressive␈αand␈αextensive␈αapplications␈αof␈αhashing␈αappear␈αin␈αHLISP␈α([Got 74],␈α[Ter 75]).
␈↓ ↓H␈↓That␈αimplementation␈αof␈αLISP␈αsupplies␈αtwo␈αdifferent␈αkinds␈αof␈αstructures:␈αordinary␈αlist␈αstructure␈αand
␈↓ ↓H␈↓"monocopy"␈α∀structures.␈α∀Operations␈α∀are␈α∀also␈α∀supplied␈α∀for␈α∀conversion␈α∀between␈α∀types.␈α∪Extensive
␈↓ ↓H␈↓analysis␈α
of␈α
hashing␈α
effects␈α
on␈α
algorithm␈α
performance␈α
has␈α
also␈α
been␈α
done␈α
([Got 76]).␈α∞ HLISP␈α
also
␈↓ ↓H␈↓employs␈αhashing␈αin␈αits␈αimplementation␈αof␈αproperty␈αlists.␈α Property␈αlists␈αare␈αnot␈αstored␈αexplicitly,␈αbut
␈↓ ↓H␈↓rather␈αthe␈αatom␈αname␈αand␈αthe␈αproperty␈αname␈αare␈αused␈αto␈αform␈αa␈αhash␈αindex;␈αthe␈αproperty␈αvalue␈αis
␈↓ ↓H␈↓associated␈α∞with␈α∞that␈α∞hash␈α∞index.␈α∞ For␈α∞example,␈α∞␈↓αget[x;i]␈↓␈α∞hashes␈α∞with␈α∞both␈α∞␈↓αx␈↓␈α∞and␈α∞␈↓αi␈↓␈α∞to␈α∞retrieve␈α∞the
␈↓ ↓H␈↓property value.
␈↓ ↓H␈↓The␈α
other␈α
major␈α
implementations␈α
of␈α
LISP␈αalso␈α
offer␈α
specialized␈α
operations␈α
for␈α
dealing␈αwith␈α
hashed
␈↓ ↓H␈↓quantities; see [Moo 74], [Int 75], and [Bob 75].
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 240␈↓ List structure may be ␈↓↓modified␈↓ by ␈↓αrplaca␈↓ and ␈↓αrplacd␈↓, and we will discuss that in a moment.
␈↓ ↓H␈↓␈↓↓8.␈↓ λWImplications of LISP 379␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓↓CHAPTER 8
␈↓ ↓H␈↓↓␈↓ ¬~IMPLICATIONS OF LISP␈↓
␈↓ ↓H␈↓Any␈α
text␈αwhich␈α
is␈α
of␈αthe␈α
size␈α
and␈αextent␈α
of␈αthis␈α
book␈α
certainly␈αowes␈α
a␈α
word␈αof␈α
explanation␈α
to␈αits
␈↓ ↓H␈↓readers;␈αafter␈α379␈αpages␈αit␈αis␈αnot␈αfair␈αto␈αturn␈αthe␈αpage␈αand␈αfind␈αthe␈αindex.␈α This␈αsection␈αwill␈αtry␈αto
␈↓ ↓H␈↓summarize␈αwhat␈αwe␈αhave␈αaccomplished␈αin␈αthis␈αbook␈αand␈αwill␈αaddress␈αsome␈αof␈αthe␈αcurrent␈αresearch
␈↓ ↓H␈↓related to LISP-like languages.
␈↓ ↓H␈↓It␈α∞is␈α∞the␈α∂author's␈α∞belief␈α∞that␈α∂LISP␈α∞should␈α∞be␈α∂the␈α∞first␈α∞language␈α∂learned␈α∞by␈α∞persons␈α∂interested␈α∞in
␈↓ ↓H␈↓computer␈αscience.␈α As␈αa␈αlanguage␈αfor␈αstudying␈αalgorithms␈αfor␈αdata␈αstructures,␈αit␈αis␈αpresently␈α
without
␈↓ ↓H␈↓peer.␈α∀ As␈α∀you␈α∀have␈α∀seen,␈α∀the␈α∃problems␈α∀of␈α∀language␈α∀implementation␈α∀and␈α∀their␈α∃solutions␈α∀are
␈↓ ↓H␈↓describable␈αquite␈αnaturally␈α
in␈αthe␈αimplementation␈α
of␈αLISP.␈α As␈α
a␈αprogramming␈αlanguage,␈αLISP␈α
has
␈↓ ↓H␈↓powerful␈αfeatures␈αpossessed␈αby␈αfew␈αlanguages,␈αin␈αparticular␈αthe␈αuniform␈αrepresentation␈αof␈αprogram
␈↓ ↓H␈↓and data.
␈↓ ↓H␈↓We␈αhave␈αdeveloped␈αseveral␈αareas␈αof␈αprogramming␈αlanguages␈αand␈αdata␈αstructures␈αin␈αthis␈αbook␈αand
␈↓ ↓H␈↓have hinted at future possibilities in several of those areas:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α∂Mathematical␈α∂models:␈α∂This␈α∂indicates␈α∂some␈α∂of␈α∂the␈α∂theoretical␈α∂areas␈α∂which␈α∂are␈α⊂available,␈α∂using
␈↓ ↓H␈↓␈↓ ↓hLISP␈α⊃as␈α⊃the␈α∩basis␈α⊃for␈α⊃mathematical␈α∩studies␈α⊃of␈α⊃algorithms.␈α⊃ This␈α∩is␈α⊃not␈α⊃a␈α∩purely␈α⊃theoretical
␈↓ ↓H␈↓␈↓ ↓hinterest.␈α The␈αareas␈αof␈αprogram␈αcorrectness␈α
need␈αdevelopment.␈αMany␈αof␈αthe␈αaspects␈αof␈α
LISP␈αare
␈↓ ↓H␈↓␈↓ ↓hattractive␈α∪from␈α∩this␈α∪perspective.␈α∩ The␈α∪issue␈α∩of␈α∪programming␈α∩language␈α∪semantics␈α∪also␈α∩needs
␈↓ ↓H␈↓␈↓ ↓hclarification.␈α The␈αstudy␈αof␈αsemantics␈α
is␈αmotivated␈αby␈αthe␈αdesire␈α
to␈αhave␈αa␈αtool␈αfor␈αdescribing␈α
the
␈↓ ↓H␈↓␈↓ ↓hmeaning␈α⊂of␈α⊂constructs␈α⊂of␈α⊂a␈α⊃language;␈α⊂in␈α⊂particular,␈α⊂a␈α⊂tool␈α⊃of␈α⊂the␈α⊂power␈α⊂and␈α⊂clarity␈α⊃of␈α⊂BNF
␈↓ ↓H␈↓␈↓ ↓hdescriptions␈α∃of␈α∀the␈α∃syntax␈α∃of␈α∀languages.␈α∃We␈α∃have␈α∀talked␈α∃a␈α∃bit␈α∀about␈α∃semantic␈α∃issues␈α∀in
␈↓ ↓H␈↓␈↓ ↓hSection 3.13.
␈↓ ↓H␈↓␈↓↓2.␈↓␈αGeneralized␈αcontrol␈αstructures:␈αWe␈αhinted␈αat␈αsome␈αof␈αthe␈αoptions␈αunder␈αconsideration␈αfor␈αcontrol
␈↓ ↓H␈↓␈↓ ↓hof␈α⊃algorithms.␈α⊃The␈α⊃work␈α⊂on␈α⊃generalized␈α⊃access␈α⊃and␈α⊂control,␈α⊃also␈α⊃known␈α⊃as␈α⊂"spaghetti stacks"
␈↓ ↓H␈↓␈↓ ↓h([Bob 73a]),␈αis␈αof␈α
current␈αinterest␈αand␈α
many␈αof␈αits␈αmotivations␈α
and␈αimplications␈αshould␈α
be␈αmore
␈↓ ↓H␈↓␈↓ ↓hunderstandable␈αnow.␈αThe␈αdevices␈αwhich␈αare␈αrequired␈αfor␈αsuch␈αgeneral␈αcontrol␈αalso␈αcome␈αdirectly
␈↓ ↓H␈↓␈↓ ↓hfrom␈α∂the␈α∂LISP␈α∞experience.␈α∂ Devices␈α∂like␈α∂"spaghetti stacks"␈α∞serve␈α∂for␈α∂implementation␈α∂of␈α∞higher
␈↓ ↓H␈↓␈↓ ↓hlevel language constructs like pattern directed invocation.
␈↓ ↓H␈↓␈↓↓380 Implications of LISP␈↓ B8.␈↓
␈↓ ↓H␈↓␈↓↓3.␈↓␈αInterpreter/compilers:␈αThis␈αis␈αan␈αinteresting␈αarea␈αwhich␈αbegins␈αto␈αresolve␈αthe␈αdichotomy␈αbetween
␈↓ ↓H␈↓␈↓ ↓hcompilation␈α
and␈α
interpretation.␈α
Work␈α
was␈α
done␈αin␈α
[Mit 70],␈α
but␈α
little␈α
has␈α
been␈α
done␈αsince.␈α
Again,
␈↓ ↓H␈↓␈↓ ↓hLISP is a natural vehicle for discussing this topic.
␈↓ ↓H␈↓␈↓↓4.␈↓␈α∞Implementation␈α∞tricks␈α
and␈α∞machine␈α∞organization:␈α∞In␈α
the␈α∞past␈α∞LISP␈α
has␈α∞been␈α∞the␈α∞originator␈α
of
␈↓ ↓H␈↓␈↓ ↓hseveral,␈α∂now␈α∂every-day,␈α∞programming␈α∂tricks.␈α∂Current␈α∂production␈α∞versions␈α∂of␈α∂LISP␈α∂continue␈α∞to
␈↓ ↓H␈↓␈↓ ↓hdevelop␈α∂sophisticated␈α⊂techniques␈α∂for␈α∂management␈α⊂of␈α∂very␈α∂large␈α⊂spaces,␈α∂representation␈α⊂of␈α∂data
␈↓ ↓H␈↓␈↓ ↓hstructures,␈α
and␈α
execution␈α
of␈α
complex␈α
algorithms.␈α
Many␈α
of␈α
those␈α
ideas␈α
have␈α
direct␈α
implications␈α
for
␈↓ ↓H␈↓␈↓ ↓hthe development of hardware for LISP like languages.
␈↓ ↓H␈↓The␈α⊂main␈α∂purpose␈α⊂of␈α⊂this␈α∂epilog␈α⊂is␈α⊂to␈α∂tie␈α⊂together␈α⊂most␈α∂of␈α⊂the␈α⊂material␈α∂we␈α⊂have␈α⊂studied.␈α∂The
␈↓ ↓H␈↓underlying␈α∂thread␈α∞in␈α∂our␈α∂study␈α∞has␈α∂been␈α∞the␈α∂internal␈α∂and␈α∞external␈α∂behavior␈α∞of␈α∂LISP.␈α∂A␈α∞rather
␈↓ ↓H␈↓natural␈α
vehicle␈αto␈α
unify␈αthese␈α
topics␈αis␈α
the␈α
design␈αof␈α
a␈αnew␈α
LISP-like␈αlanguage.␈α
Language␈αdesign␈α
is
␈↓ ↓H␈↓not␈α⊂a␈α⊂pasttime␈α⊂to␈α⊂be␈α⊂entered␈α⊂into␈α⊃lightly.␈α⊂We␈α⊂will␈α⊂therefore␈α⊂sketch␈α⊂an␈α⊂existing␈α⊃LISP␈α⊂extension
␈↓ ↓H␈↓named EL1. The name EL1 is derived from Extensible Language/1.
␈↓ ↓H␈↓There␈α∂are␈α∂two␈α∞basic␈α∂views␈α∂in␈α∞programming␈α∂language␈α∂design:␈α∞one␈α∂approach␈α∂is␈α∞to␈α∂design␈α∂a␈α∞small
␈↓ ↓H␈↓language,␈αcalled␈αa␈αbase␈αlanguage,␈αwhich␈αhas␈αsufficent␈αexpressive␈αpower␈αto␈αallow␈αits␈αuser␈αto␈αmold␈αa
␈↓ ↓H␈↓special␈α∞language␈α
from␈α∞that␈α
base.␈α∞This␈α
is␈α∞called␈α
the␈α∞"core"␈α
approach␈α∞and␈α
such␈α∞base␈α∞languages␈α
are
␈↓ ↓H␈↓called␈α∪extensible␈α∀languages.␈α∪ The␈α∪alternative,␈α∀called␈α∪the␈α∀"shell"␈α∪approach,␈α∪is␈α∀to␈α∪design␈α∀a␈α∪full
␈↓ ↓H␈↓language,␈α⊃capable␈α⊃of␈α⊃covering␈α⊃a␈α⊃specific␈α⊃area.␈α⊂That␈α⊃area␈α⊃may␈α⊃only␈α⊃cover␈α⊃a␈α⊃special␈α⊃domain␈α⊂of
␈↓ ↓H␈↓algorithms or might encompass ␈↓↓all␈↓ algorithmic processes.
␈↓ ↓H␈↓The␈α∞"shell"␈α∞approach␈α∞to␈α∞general␈α∞purpose␈α∞languages␈α∞is␈α∞best␈α∞exemplified␈α∞by␈α∞PL/1.␈α∞ This␈α
approach
␈↓ ↓H␈↓attempts␈α
to␈α
build␈α
a␈α
language␈α
which␈α
encompasses␈α
all␈α
the␈α
programing␈α
language␈α
features␈α
which␈α
one
␈↓ ↓H␈↓might␈αever␈αwant.␈αPl/1␈α
is␈αan␈αagglutination␈αof␈αFORTRAN,␈α
COBOL␈αand␈αAlgol.␈αThe␈αapproach␈α
gives
␈↓ ↓H␈↓rise␈αto␈α
many␈αproblems.␈α
Of␈αnecessity,␈α
the␈αlanguage␈αis␈α
large;␈αunless␈α
care␈αis␈α
taken␈αa␈α
programmer␈αwill
␈↓ ↓H␈↓have␈α∞difficulties␈α
in␈α∞learning␈α∞the␈α
language.␈α∞Even␈α∞if␈α
a␈α∞small␈α
subset␈α∞is␈α∞presented␈α
to␈α∞a␈α∞beginner,␈α
the
␈↓ ↓H␈↓occurrence␈αof␈αbugs␈αin␈αa␈αuser␈αprogram␈αmay␈αcause␈αmysterious␈αresults␈αif␈αthose␈αbugs␈αhappen␈αto␈αinvoke
␈↓ ↓H␈↓features␈α∪outside␈α∩the␈α∪subset.␈α∩ Also␈α∪the␈α∩language␈α∪implementor␈α∩is␈α∪in␈α∩for␈α∪a␈α∩hard␈α∪time;␈α∩language
␈↓ ↓H␈↓processors␈α
will␈α
have␈α
to␈α
be␈α
cognizant␈α
of␈α
␈↓↓all␈↓␈α∞the␈α
language␈α
features␈α
even␈α
if␈α
the␈α
user␈α
wishes␈α∞to␈α
work
␈↓ ↓H␈↓within␈α∀a␈α∃small␈α∀subset.␈α∃The␈α∀problems␈α∀of␈α∃optimization␈α∀are␈α∃compounded␈α∀immensely,␈α∃since␈α∀the
␈↓ ↓H␈↓interaction of language features may well lead to torturous code.
␈↓ ↓H␈↓The␈α⊃"shell"␈α⊂approach␈α⊃presents␈α⊃severe␈α⊂problems,␈α⊃but␈α⊂the␈α⊃"core"␈α⊃approach␈α⊂of␈α⊃extensibility␈α⊃is␈α⊂not
␈↓ ↓H␈↓without␈α∂flaw.␈α⊂There␈α∂are␈α∂non-trivial␈α⊂research␈α∂areas␈α∂involved␈α⊂in␈α∂developing␈α∂smooth␈α⊂and␈α∂efficient
␈↓ ↓H␈↓means␈α
of␈α
describing␈α
the␈α
syntax,␈α
pragmatics␈α∞and␈α
semantics␈α
of␈α
user␈α
defined␈α
data␈α∞structures,␈α
control
␈↓ ↓H␈↓structures and operations.
␈↓ ↓H␈↓An␈α
extensible␈α
language␈α
is␈α
designed␈α
to␈α
supply␈α
a␈α
base␈α
language,␈α
which␈α
has␈α
sufficient␈α∞handles␈α
such
␈↓ ↓H␈↓that␈α
a␈αuser␈α
can␈αdescribe␈α
new␈αdata␈α
structures,␈αnew␈α
operations,␈αand␈α
new␈αcontrol␈α
structures.␈αThese␈α
new
␈↓ ↓H␈↓objects␈α
are␈α
described␈α
in␈α
terms␈α
of␈α
combinations␈αof␈α
constructs␈α
in␈α
the␈α
base␈α
language.␈α
Extensibility␈αis
␈↓ ↓H␈↓implicitly␈α
committed␈αto␈α
the␈αpremiss␈α
that␈αthe␈α
power␈αof␈α
high␈αlevel␈α
languages␈αis␈α
primarily␈αnotational
␈↓ ↓H␈↓rather␈α∪than␈α∪computational.␈α∪That␈α∩is␈α∪apparent␈α∪from␈α∪our␈α∩experience␈α∪with␈α∪high␈α∪level␈α∩numerical
␈↓ ↓H␈↓␈↓↓8.␈↓ λWImplications of LISP 381␈↓
␈↓ ↓H␈↓languages.␈α Their␈αnotations␈αallow␈αus␈αto␈αexpress␈αour␈αproblems␈αin␈αmathematics-like␈αstatements,␈αrather
␈↓ ↓H␈↓than coding in the order code of the machine.
␈↓ ↓H␈↓Like␈αLISP,␈αthe␈αextensible␈αlanguage␈αEL1␈αmaps␈αprograms␈αonto␈αdata␈αstructures.␈αEL1␈αhas␈αricher␈αdata
␈↓ ↓H␈↓types␈α
including␈αintegers,␈α
characters,␈αpointers,␈α
and␈αstructures.␈α
Its␈αsyntax␈α
is␈αdescribed␈α
in␈αBNF␈α
and␈αa
␈↓ ↓H␈↓mapping␈αfrom␈αwell-formed␈αsyntactic␈αunits␈αto␈αdata␈αstructures␈αis␈αgiven.␈αThe␈αEL1␈αevaluator␈αis␈αwritten
␈↓ ↓H␈↓in␈α∂EL1␈α∂and␈α∂manipulates␈α∂the␈α∂data-structure␈α∞representation␈α∂of␈α∂EL1␈α∂programs␈α∂in␈α∂a␈α∂manner␈α∞totally
␈↓ ↓H␈↓analogous to the LISP ␈↓αeval␈↓ function. Now for more detail:
␈↓ ↓H␈↓The␈α
syntax␈αof␈α
EL1␈α
constructs␈αis␈α
similar␈αto␈α
that␈α
of␈αM-expression␈α
LISP.␈α
The␈αdetails␈α
are␈αnot␈α
relevant
␈↓ ↓H␈↓and␈α⊃are␈α∩best␈α⊃left␈α⊃to␈α∩the␈α⊃user's␈α⊃manual,␈α∩[EL1 74].␈α⊃ What␈α⊃␈↓↓is␈↓␈α∩important␈α⊃is␈α∩the␈α⊃interrelationships
␈↓ ↓H␈↓between␈αthe␈αconstucts␈αof␈αthe␈αlanguage␈αand␈αtheir␈αdata␈αstructure␈αrepresentations.␈α That␈αis,␈αwe␈αwish␈α
to
␈↓ ↓H␈↓develop␈αa␈αrepresentation␈αof␈αthe␈αabstract␈αsyntax␈αof␈αEL1␈αusing␈αthe␈αdata␈αstructures␈αavailable␈αin␈αEL1.
␈↓ ↓H␈↓Our␈α
approach␈α
here␈α
is␈α
the␈α
other␈α
way␈α
round:␈α
to␈α
motivate␈α
the␈α
data␈α
structures␈α
of␈α
a␈α
language␈α∞by␈α
the
␈↓ ↓H␈↓requirements for expressing a realistic evaluator␈↓π 241␈↓.
␈↓ ↓H␈↓Consider this fragment of the LISP syntax from page 17:
␈↓ ↓H␈↓<form>␈↓ βH::= <constant> | <application> | <variable>
␈↓ ↓H␈↓<application>␈↓ βH::= <function-part>[<arg-list>]
␈↓ ↓H␈↓<arg-list>␈↓ βH::= <arg> | <arg-list>;<arg>
␈↓ ↓H␈↓These␈αequations␈αdemonstrate␈αthe␈αthree␈αkinds␈αof␈αBNF␈αequations.␈α We␈αwill␈αignore␈αthe␈αfirst␈αequation
␈↓ ↓H␈↓for the moment and concentrate our attention on the last two equations.
␈↓ ↓H␈↓The␈αLISP␈αM-to-S-expression␈αmapping␈αwill␈αmap␈αan␈α<application>␈αlike␈α␈↓αf[x;y;z]␈↓␈αonto␈α␈↓α(F␈αX␈αY␈αZ)␈↓.␈αFor
␈↓ ↓H␈↓all␈α
intents␈α
and␈α
purposes,␈α
LISP␈α
has␈α
little␈α
choice;␈α
LISP␈α
has␈α
few␈α
representations␈α
available␈α
and␈αsince
␈↓ ↓H␈↓we␈αwish␈αto␈αuse␈αthe␈αS-expr␈αrepresentation␈αas␈αthe␈αprogramming␈αlanguage,␈αthe␈αrepresentation␈αmust␈αbe
␈↓ ↓H␈↓readable.␈α In␈α the␈α∨typical␈α implementations␈α of␈α LISP,␈α∨the␈α representation␈α of␈α ␈↓αf[x;y;z]␈↓␈α∨is
␈↓ ↓H␈↓␈↓α(F . (X . (Y . (X NIL))))␈↓.␈α∀ That␈α∪requires␈α∀a␈α∪lot␈α∀of␈α∪space,␈α∀and␈α∪requires␈α∀some␈α∪decoding␈α∀by␈α∪any
␈↓ ↓H␈↓program␈αwhich␈α
is␈αto␈αuse␈α
this␈αrepresentation.␈αIf␈α
we␈αlook␈α
deeper␈αat␈αthe␈α
storage␈αrequirements␈αfor␈α
these
␈↓ ↓H␈↓two equations we see that there are differences.
␈↓ ↓H␈↓The␈α∂representation␈α∂of␈α∂an␈α∂<application>␈α∂has␈α∞␈↓↓fixed␈↓␈α∂storage␈α∂requirements;␈α∂it␈α∂desires␈α∂space␈α∂for␈α∞two
␈↓ ↓H␈↓components:␈αa␈α<function-part>␈αcomponent,␈αand␈αa␈α<arg-list>␈αcomponent.␈αWe␈αhave␈αseen␈αsuch␈αstorage
␈↓ ↓H␈↓structures␈α∂before␈α∂in␈α∂Section 7.5;␈α∂they␈α∂are␈α∂called␈α∂record␈α∂structures.␈α∂ The␈α∂name␈α∂components␈α⊂of␈α∂the
␈↓ ↓H␈↓record␈αstructure␈αcan␈αbe␈α␈↓αfun␈↓␈αand␈α␈↓αargs␈↓,␈αand␈αthe␈αselector␈αfunctions␈αare␈αimplemented␈αby␈αmatching␈αthe
␈↓ ↓H␈↓name␈α⊗components.␈α↔ Note␈α⊗that␈α↔the␈α⊗use␈α↔of␈α⊗record␈α↔structure␈α⊗is␈α↔a␈α⊗bit␈α↔freer␈α⊗than␈α↔LISP's␈α⊗list
␈↓ ↓H␈↓representation;␈α⊃we␈α⊃need␈α⊂not␈α⊃make␈α⊃a␈α⊃commitment␈α⊂to␈α⊃the␈α⊃position␈α⊃of␈α⊂the␈α⊃␈↓αfun␈↓␈α⊃component␈α⊃in␈α⊂the
␈↓ ↓H␈↓representation.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 241␈↓ Compare the following discussion with Section 7.5.
␈↓ ↓H␈↓␈↓↓382 Implications of LISP␈↓ B8.␈↓
␈↓ ↓H␈↓The␈α∂requirements␈α∂for␈α∂<arg-list>␈α∞are␈α∂different.␈α∂An␈α∂arbitrary␈α∞<arg-list>␈α∂has␈α∂a␈α∂variable␈α∂number␈α∞of
␈↓ ↓H␈↓components.␈α∪Each␈α∪component␈α∪has␈α∪the␈α∪same␈α∪characteristic:␈α∪it's␈α∪an␈α∪<arg>.␈α∪We␈α∪can␈α∀represent␈α∪a
␈↓ ↓H␈↓homogeneous␈αobject␈αlike␈α<arg-list>␈αas␈αa␈αsequence␈αwhose␈αlength␈αis␈αfixed.␈αA␈αnatural␈αstorage␈αclass␈αfor
␈↓ ↓H␈↓such␈αsequences␈αis␈αa␈αlinear␈α
array,␈αeach␈αcomponent␈αof␈αwhich␈α
is␈αan␈αitem␈αof␈αthe␈αsequence.␈α
Information
␈↓ ↓H␈↓about␈α
the␈αlength␈α
of␈αthe␈α
sequence␈αand␈α
the␈αclass␈α
to␈αwhich␈α
elements␈αof␈α
the␈αsequence␈α
belongs,␈α
can␈αbe
␈↓ ↓H␈↓stored in the "dope vector" of the representation.
␈↓ ↓H␈↓What␈α∪we␈α∀are␈α∪developing␈α∀is␈α∪a␈α∀description␈α∪of␈α∪a␈α∀class␈α∪of␈α∀storage␈α∪representations␈α∀for␈α∪language
␈↓ ↓H␈↓constructs.␈αThis␈αclass␈αof␈αstructures␈αcovers␈αthe␈αspace␈αwhich␈αLISP␈αcovers,␈αbut␈αpartitions␈αit␈αdifferently.
␈↓ ↓H␈↓More␈α⊂information␈α⊃is␈α⊂stored␈α⊃explicitly,␈α⊂and␈α⊂the␈α⊃representations␈α⊂are␈α⊃more␈α⊂discriminating␈α⊃in␈α⊂their
␈↓ ↓H␈↓storage␈α∪requirements.␈α∪Assuming␈α∪that␈α∪the␈α∪resulting␈α∩structures␈α∪are␈α∪made␈α∪data␈α∪structures␈α∪of␈α∩the
␈↓ ↓H␈↓language, we can then write a LISP-like ␈↓αeval␈↓ which runs on these data structures.
␈↓ ↓H␈↓Our␈αrefinement␈α
is␈αnot␈αwithout␈α
penalty.␈αWe␈α
are␈αin␈αfact␈α
imposing␈αa␈αtype␈α
structure␈αon␈α
the␈αlanguage.
␈↓ ↓H␈↓For␈α∀our␈α∀theoretical␈α∀studies␈α∀we␈α∀know␈α∀that␈α∀such␈α∀restrictions␈α∀are␈α∀not␈α∀always␈α∀desireable.␈α∀ Type
␈↓ ↓H␈↓restrictions have drawbacks from practical considerations as well.
␈↓ ↓H␈↓The type structure becomes more apparent when we consider the remaining syntax equation:
␈↓ ↓H␈↓<form>␈↓ βH::= <constant> | <application> | <variable>
␈↓ ↓H␈↓Consistent␈α∃with␈α∃our␈α∃treatment␈α∀of␈α∃record␈α∃structures␈α∃and␈α∀sequences,␈α∃we␈α∃should␈α∃develop␈α∀some
␈↓ ↓H␈↓representation␈α∩for␈α∪<form>.␈α∩ In␈α∩LISP,␈α∪no␈α∩storage␈α∪was␈α∩allocated␈α∩for␈α∪the␈α∩representation␈α∪of␈α∩such
␈↓ ↓H␈↓alternative␈α⊂BNF␈α∂equations;␈α⊂the␈α∂recognition␈α⊂was␈α∂done␈α⊂by␈α∂recognizers␈α⊂embedded␈α∂in␈α⊂a␈α∂conditional
␈↓ ↓H␈↓expression:
␈↓ ↓H␈↓α␈↓ ¬_[is-const[x] → ...
␈↓ ↓H␈↓α␈↓ ¬_ is-app[x] → ...
␈↓ ↓H␈↓α␈↓ ¬_ is-var[x] →
␈↓ ↓H␈↓α␈↓ ¬_ ␈↓
t␈↓ → ... what to do if ␈↓αx␈↓ is ␈↓↓not␈↓ a form ...
␈↓ ↓H␈↓In␈α
EL1,␈α
every␈α∞data␈α
item␈α
has␈α
an␈α∞associated␈α
type.␈α
Since␈α
we␈α∞are␈α
representing␈α
language␈α∞constructs␈α
as
␈↓ ↓H␈↓data␈αstructures␈αthey␈αwill␈αalso␈αhave␈αassociated␈αtypes.␈α To␈αdetermine␈αif␈αsomething␈αis␈αan␈α<application>
␈↓ ↓H␈↓requires␈αonly␈α
that␈αwe␈α
examine␈αthe␈α
associated␈αtype.␈α
The␈αquestion␈α
then␈αarises:␈α
what␈αkind␈α
of␈αobject␈α
is
␈↓ ↓H␈↓to␈α
be␈α
associated␈αwith␈α
an␈α
object␈αlike␈α
<form>?␈α
At␈αany␈α
one␈α
time␈α
an␈αobject␈α
of␈α
type␈α<form>␈α
is␈α
one␈αof␈α
the
␈↓ ↓H␈↓three␈αalternatives.␈αThe␈αEL1␈αsolution␈αis␈αto␈αassign␈αa␈αpointer-like␈αdata␈αobject␈αas␈αthe␈αrepresentation␈αof
␈↓ ↓H␈↓such objects. The type of the pointer is constrained to point at one of the alternatives.
␈↓ ↓H␈↓␈↓↓8.␈↓ λWImplications of LISP 383␈↓
␈↓ ↓H␈↓Let's compare LISP:
␈↓ ↓H␈↓Given an application ␈↓αf[x;A;1]␈↓ we represent it as a constant ␈↓α(F X (QUOTE A) 1)␈↓. That is:
␈↓ ↓H␈↓␈↓ ∧_␈↓λr␈↓βLISP␈↓∞(␈↓αf[x;A;1]␈↓∞)␈↓ = ␈↓α(F X (QUOTE A) 1)␈↓.
␈↓ ↓H␈↓We␈α∞wish␈α∞to␈α∞represent␈α∂this␈α∞application␈α∞as␈α∞a␈α∂constant␈α∞in␈α∞EL1␈α∞as␈α∂well.␈α∞We␈α∞need␈α∞some␈α∂notation␈α∞for
␈↓ ↓H␈↓record␈α∩structures␈α∩and␈α∩sequence␈α∩constants.␈α∩ A␈α∩record␈α⊃constant␈α∩of␈α∩type␈α∩␈↓αt␈↓␈α∩will␈α∩be␈α∩represented␈α⊃as
␈↓ ↓H␈↓<␈↓βt␈↓ c␈↓β1␈↓; ... ;c␈↓βn␈↓>␈↓π 242␈↓. A sequence of type ␈↓αt␈↓ will be represented as (␈↓βt␈↓s␈↓β1␈↓; ... ;s␈↓βn␈↓).
␈↓ ↓H␈↓Then ␈↓λr␈↓βEL1␈↓∞(␈↓αf[x;A;1]␈↓∞)␈↓ = <␈↓βapp␈↓λr␈↓βEL1␈↓∞(␈↓αf␈↓∞)␈↓, <␈↓βarg-list␈↓λr␈↓βEL1␈↓∞(␈↓αx␈↓∞)␈↓, ␈↓λr␈↓βEL1␈↓∞(␈↓αA␈↓∞)␈↓, ␈↓λr␈↓βEL1␈↓∞(␈↓α1␈↓∞)␈↓)>>
␈↓ ↓H␈↓We␈αhave␈αsuppressed␈α
much␈αof␈αthe␈αdetail␈α
because␈αeach␈αof␈αthe␈α
components␈αof␈αthe␈αrepresentation␈α
must
␈↓ ↓H␈↓also have type information.
␈↓ ↓H␈↓The␈α∞structured␈α∞items␈α∞in␈α∞LISP␈α∞are␈α∞built␈α∞from␈α∞dotted␈α∞pairs;␈α∞the␈α∞structured␈α∞items␈α∞in␈α∞EL1␈α∂are␈α∞built
␈↓ ↓H␈↓from␈α∩sequences␈α∩(or␈α∩lists),␈α∪from␈α∩records␈α∩(or␈α∩structures),␈α∪and␈α∩from␈α∩pointers␈α∩(or␈α∪references).␈α∩The
␈↓ ↓H␈↓difference␈αis␈αthat␈αthe␈αEL1␈αuser␈αhas␈αmore␈αchoice␈αover␈αthe␈αunderlying␈αrepresentation.␈αThis␈αcan␈αlead
␈↓ ↓H␈↓to␈αmore␈αefficient␈αutilization␈αof␈αstorage␈αand␈α
perhaps␈αmore␈αefficient␈αprograms.␈α Since␈αthe␈αevaluator␈α
is
␈↓ ↓H␈↓just␈αan␈α
EL1␈αprogram,␈α
these␈αconsiderations␈αcarry␈α
over␈αto␈α
the␈αevaluation␈αprocess.␈α
EL1␈αallows␈α
us␈αto
␈↓ ↓H␈↓␈↓↓represent␈↓␈α∂the␈α∂data␈α∂structures␈α∞of␈α∂the␈α∂evaluation␈α∂process␈α∞in␈α∂terms␈α∂closer␈α∂to␈α∂actual␈α∞implementation.
␈↓ ↓H␈↓Both␈α∞LISP␈α∞and␈α∞EL1␈α
allow␈α∞us␈α∞to␈α∞␈↓↓express␈↓␈α
realistic␈α∞implementations,␈α∞however␈α∞LISP␈α∞will␈α
ultimately
␈↓ ↓H␈↓represent its structures as dotted pairs.
␈↓ ↓H␈↓This␈α↔realism␈α↔of␈α↔representation␈α↔carries␈α↔over␈α⊗to␈α↔the␈α↔evaluation␈α↔process␈α↔which␈α↔runs␈α↔on␈α⊗the
␈↓ ↓H␈↓representation.␈α∞The␈α∞language␈α∞is␈α∞capable␈α∞of␈α∞accurately␈α∞representing␈α∞more␈α∞of␈α∞the␈α∞techniques␈α
which
␈↓ ↓H␈↓occur␈αin␈αa␈α
language␈αimplementation.␈αThe␈αlanguage␈α
supplies␈αstorage␈αmanagement␈α
primitives␈αwhich
␈↓ ↓H␈↓allow the creation of stack-like objects as well as the heap-stored items of LISP.
␈↓ ↓H␈↓The␈α
language␈αoffers␈α
the␈α
user␈αthe␈α
ability␈α
to␈α␈↓↓define␈↓␈α
abstract␈αdata␈α
structures␈α
in␈αa␈α
manner␈α
similar␈αto
␈↓ ↓H␈↓that␈α
we␈αhave␈α
been␈αadvocating␈α
informally.␈α
Given␈αthe␈α
finer␈αpartition␈α
of␈αstorage␈α
structures,␈α
the␈αuser
␈↓ ↓H␈↓can␈αmap␈αthose␈αstructures␈αonto␈αmore␈α
frugal␈αrepresentations␈αthan␈αLISP,␈αand␈αsince␈α
the␈αtype-checking
␈↓ ↓H␈↓is␈α⊂built␈α⊃into␈α⊂the␈α⊃language,␈α⊂the␈α⊃language␈α⊂processors␈α⊂can␈α⊃check␈α⊂the␈α⊃consistency␈α⊂of␈α⊃the␈α⊂parameter
␈↓ ↓H␈↓passing.␈α Relating␈αthe␈αabstract␈αwith␈αthe␈αrepresentation␈αrequires␈αsome␈αcare.␈αSupplying␈αa␈αcomfortable
␈↓ ↓H␈↓interface␈αbetween␈αthese␈αtwo␈αdomains␈αis␈αa␈αnon-trivial␈αproblem.␈αEL1␈αsupplies␈α"lifting"␈αand␈α
"lowering"
␈↓ ↓H␈↓mechanisms to aid in this problem; the result is not completely satisfactory.
␈↓ ↓H␈↓We␈α∩have␈α∩frequently␈α∩seen␈α∩how␈α∩easy␈α∩it␈α∩has␈α∩been␈α∩to␈α∩extend␈α∩LISP␈α∩by␈α∩modifying␈α∩␈↓αeval␈↓.␈α∩ This␈α∩is
␈↓ ↓H␈↓particularly␈αeasy␈αbecause␈αwe␈αare␈α
making␈αmodifications␈αat␈αthe␈αlevel␈αof␈α
data-structure␈αrepresentation
␈↓ ↓H␈↓of␈α
programs.␈α
In␈α
EL1␈α
we␈α∞wish␈α
to␈α
make␈α
the␈α
extensions␈α
at␈α∞the␈α
level␈α
of␈α
concrete␈α
syntax,␈α∞rather␈α
than
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 242␈↓␈αWe␈αhave␈αsuppressed␈αthe␈α
explicit␈αnaming␈αof␈αeach␈αcomponent␈α
of␈αthe␈αrecord.␈αWe␈αassume␈α
that␈αa
␈↓ ↓H␈↓"template"␈α∀of␈α∀each␈α∀type␈α∀␈↓αt␈↓␈α∀is␈α∀available.␈α∀That␈α∀template␈α∀can␈α∀be␈α∀consulted␈α∀to␈α∃determine␈α∀which
␈↓ ↓H␈↓component is referenced.
␈↓ ↓H␈↓␈↓↓384 Implications of LISP␈↓ B8.␈↓
␈↓ ↓H␈↓abstract␈α∩syntax␈α∩as␈α∩LISP␈α∩does␈↓π 243␈↓.␈α⊃ EL1␈α∩can␈α∩do␈α∩this␈α∩by␈α⊃using␈α∩a␈α∩parser␈α∩which␈α∩is␈α⊃table-driven,
␈↓ ↓H␈↓operating␈αon␈αan␈αmodifiable␈αset␈αof␈αproductions.␈αTo␈αintroduce␈αa␈αnew␈αconstruct␈αinto␈αthe␈αlanguage␈αwe
␈↓ ↓H␈↓need␈α∂to␈α∞supply␈α∂the␈α∞concrete␈α∂syntax␈α∞for␈α∂the␈α∂item,␈α∞its␈α∂abstract␈α∞systax,␈α∂a␈α∞mapping␈α∂from␈α∂concrete␈α∞to
␈↓ ↓H␈↓abstract,␈αand␈αits␈αpragmatics␈αexpressed␈αas␈αadditions␈αto␈αthe␈αevaluator.␈α However␈αthere␈αmay␈αbe␈αwider
␈↓ ↓H␈↓implications␈α∞in␈α∂the␈α∞language␈α∞and␈α∂more␈α∞general␈α∂features␈α∞are␈α∞required␈↓π 244␈↓.␈α∂ The␈α∞field␈α∂of␈α∞language
␈↓ ↓H␈↓design is still quite young and tentative.
␈↓ ↓H␈↓Though␈αLISP␈αis␈αa␈αfull␈αtwenty␈αyears␈αold,␈αit␈αis␈αstill␈αa␈αfertile␈αresearch␈αarea.␈α Projects␈αare␈αinvestigating
␈↓ ↓H␈↓LISP␈α_extensions␈α_in␈α_several␈α_directions.␈α_ [Car 76]␈α_investigates␈α_the␈α_possibilities␈α_of␈α→adding␈α_a
␈↓ ↓H␈↓type-structure␈α∞to␈α∞LISP,␈α∞giving␈α∞a␈α∞strong␈α∞typed␈α∞programming␈α∞language␈α∞and␈α∞a␈α∞precise␈α∞formalism␈α∞in
␈↓ ↓H␈↓which␈α
properties␈α
of␈α∞Typed␈α
LISP␈α
programs␈α∞can␈α
be␈α
discussed.␈α∞ This␈α
project␈α
supplies␈α∞an␈α
Algol-like
␈↓ ↓H␈↓user language as well as develops interesting theoretical results.
␈↓ ↓H␈↓Several␈αpeople␈αhave␈αsupplied␈αparsers␈αwhich␈αgive␈αthe␈αuser␈αan␈αAlgol-like␈αsyntax␈α([Mli 73],␈α[Pra 76]).
␈↓ ↓H␈↓Extensions to the ideas of SDIO Section 9.4 are being pursued.
␈↓ ↓H␈↓Programming␈α⊂language␈α⊃semantics␈α⊂is␈α⊂being␈α⊃coupled␈α⊂with␈α⊂the␈α⊃realities␈α⊂of␈α⊃programming␈α⊂language
␈↓ ↓H␈↓design in a successor of [LCF 72]. This is being built on the LISP experience.
␈↓ ↓H␈↓LISP is the direct source of inspiration for two current MIT projects.
␈↓ ↓H␈↓For␈α∃several␈α∃years␈α∃C. Hewitt␈α∃has␈α∀been␈α∃developing␈α∃an␈α∃interesting␈α∃philosophy␈α∃of␈α∀computation.
␈↓ ↓H␈↓Building␈α⊂on␈α⊂his␈α⊂experience␈α⊂with␈α⊃LISP,␈α⊂he␈α⊂developed␈α⊂PLANNER␈α⊂[Hew 72],␈α⊂and␈α⊃more␈α⊂recently
␈↓ ↓H␈↓refined␈αthse␈αideas␈αin␈αa␈αmethodology␈αcalled␈αActors␈α([Hew 74],␈α[Hew 76]).␈α One␈αof␈αthe␈αaims␈αof␈αthese
␈↓ ↓H␈↓investigations␈α∞is␈α∞to␈α∞develop␈α
a␈α∞self-sufficient␈α∞description␈α∞of␈α
modern␈α∞computation␈α∞much␈α∞in␈α∞the␈α
way
␈↓ ↓H␈↓that␈α
the␈α
␈↓λλ␈↓-calculus␈α
gave␈α
a␈αfoundation␈α
to␈α
the␈α
notion␈α
of␈αcomputable␈α
function.␈α
The␈α
aim␈α
therefore␈αis
␈↓ ↓H␈↓much␈α∞more␈α∞than␈α∞just␈α∞to␈α∞develop␈α∞another␈α∞programming␈α∞language.␈α∞Along␈α∞the␈α∞way,␈α∞however,␈α
these
␈↓ ↓H␈↓projects␈α⊃have␈α⊃developed␈α⊂some␈α⊃of␈α⊃the␈α⊂most␈α⊃notable␈α⊃ideas␈α⊂of␈α⊃advanced␈α⊃programming␈α⊂languages.
␈↓ ↓H␈↓From␈α⊗the␈α↔PLANNER␈α⊗experience,␈α↔partially␈α⊗implemented␈α↔in␈α⊗[Mic 71],␈α↔evolved␈α⊗the␈α↔ideas␈α⊗of
␈↓ ↓H␈↓pattern-directed␈α∃invocation;␈α∃see␈α∃Section 2.4.␈α∀ This␈α∃idea␈α∃gave␈α∃PLANNER␈α∀a␈α∃new␈α∃way␈α∃to␈α∀call
␈↓ ↓H␈↓procedures,␈αand␈α
its␈αimplementation␈α
in␈αMicro-PLANNER␈α
gave␈αresearchers␈α
new␈αpower␈αof␈α
expression
␈↓ ↓H␈↓much␈α∀in␈α∀the␈α∀way␈α∪that␈α∀LISP␈α∀improved␈α∀over␈α∪machine␈α∀language␈α∀several␈α∀years␈α∀before.␈α∪ These
␈↓ ↓H␈↓investigations␈α∂generated␈α∂much␈α∂controversy␈α∂and␈α∂stimulated␈α∂more␈α∂research␈α∂in␈α∂language␈α⊂design␈α∂for
␈↓ ↓H␈↓artificial␈α
intelligence;␈α
see␈α
[Bob 74],␈α
[Con 73],␈α
[QA4 72].␈α
The␈α
lessons␈α
of␈α
PLANNER␈α
led␈α
to␈α
Actors
␈↓ ↓H␈↓and␈αa␈αstudy␈α
of␈αthe␈αcontrol␈αaspects␈α
of␈αprogramming␈αlanguages.␈α
From␈αthese␈αinvestigations␈αHewitt␈α
has
␈↓ ↓H␈↓developed␈α⊂a␈α⊂model␈α⊂which␈α⊂looks␈α⊂on␈α⊂control␈α⊂as␈α⊂an␈α⊂activity␈α⊂of␈α⊂passing␈α⊂message␈α⊂between␈α∂program
␈↓ ↓H␈↓modules.␈α↔ Recently,␈α⊗Hewitt's␈α↔efforts␈α⊗have␈α↔again␈α⊗stimulated␈α↔others␈α⊗to␈α↔examine␈α⊗programming
␈↓ ↓H␈↓languages more closely.
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 243␈↓␈α∩To␈α∩program␈α∩in␈α∩the␈α∩abstract␈α∩syntax␈α∩would␈α∩be␈α∩possible,␈α∩but␈α∩messy.␈α∩We␈α∩would␈α∪be␈α∩writing
␈↓ ↓H␈↓constants consisting of pointers, records, and sequences, rather than the list notation of LISP.
␈↓ ↓H␈↓␈↓π 244␈↓␈αFor␈αexample,␈αif␈αnew␈αcontrol␈αstructures␈αare␈αdesired,␈αmajor␈αrevision␈αof␈αthe␈αinner␈αstructure␈αof␈αthe
␈↓ ↓H␈↓language may be necessary ([Pre 76b]).
␈↓ ↓H␈↓␈↓↓8.␈↓ λWImplications of LISP 385␈↓
␈↓ ↓H␈↓G.␈αSussman␈αand␈αG.␈αSteele␈αhave␈αbeen␈αdeveloping␈αa␈αlanguage␈αnamed␈αSCHEME␈α([Sus 75],␈α[Ste 76b],
␈↓ ↓H␈↓and␈α∂[Ste 76c])␈α∂which␈α⊂was␈α∂begun␈α∂as␈α⊂an␈α∂experiment␈α∂to␈α∂understand␈α⊂and␈α∂implement␈α∂several␈α⊂of␈α∂the
␈↓ ↓H␈↓ideas␈α∞of␈α∞Hewitt.␈α∞ The␈α∞result␈α∞is␈α∞a␈α∞dialect␈α∞of␈α∞LISP␈α∞which␈α∞uses␈α∞static␈α∞binding␈α∞rather␈α∂than␈α∞dynamic
␈↓ ↓H␈↓binding.␈α⊃The␈α∩interpreter␈α⊃is␈α⊃built␈α∩in␈α⊃the␈α∩spirit␈α⊃of␈α⊃[Con 73]␈α∩and␈α⊃is␈α⊃similar␈α∩to␈α⊃the␈α∩evaluator␈α⊃of
␈↓ ↓H␈↓Section 4.8.␈α∂ The␈α∞result␈α∂is␈α∂an␈α∞interpreter␈α∂which␈α∂makes␈α∞the␈α∂control␈α∂aspects␈α∞of␈α∂the␈α∂language␈α∞much
␈↓ ↓H␈↓more␈α∂explicit.␈α∂ Using␈α∂SCHEME,␈α∂Steele␈α∂and␈α∂Sussman␈α∞have␈α∂been␈α∂able␈α∂to␈α∂illuminate␈α∂many␈α∂of␈α∞the
␈↓ ↓H␈↓control and access problems of programming languages.
␈↓ ↓H␈↓In␈αthese␈α
two␈αprojects␈αwe␈α
see␈αtwo␈αviews␈α
of␈αcomputation:␈α
the␈αphilosophical␈αand␈α
the␈αtool␈αbuilder.␈α
Both
␈↓ ↓H␈↓are important; together they are developing an impressive array of knowledge.
␈↓ ↓H␈↓Finally,␈αLISP␈αis␈αbeing␈αused␈αas␈αan␈αeffective␈αtool␈αfor␈αthe␈αdesign␈αof␈αinteractive␈αprogramming␈αsystems.
␈↓ ↓H␈↓The␈α∀successful␈α∀development␈α∀of␈α∀programming␈α∀systems␈α∀which␈α∀integrate␈α∀all␈α∀phases␈α∀of␈α∀program
␈↓ ↓H␈↓creation,␈α
debugging␈α
and␈α
optimization,␈α∞will␈α
be␈α
based␈α
on␈α
LISP␈α∞user's␈α
experience.␈α
One␈α
of␈α∞the␈α
most
␈↓ ↓H␈↓promising sytems is EL1 ([Wegb 70], [Che 76]).
␈↓ ↓H␈↓Many␈α
people␈α
find␈α
it␈α
curious␈α
that␈α
LISP␈α
has␈α
survived␈α
so␈α
long␈α
and␈α
so␈α
well.␈α
It␈α
is␈α
not␈α∞supported␈α
by
␈↓ ↓H␈↓any␈α
organization␈α
or␈α
computer␈α
manufacturer␈α
yet␈α
it␈αflourishes␈α
and␈α
continues␈α
to␈α
attract␈α
many␈α
of␈αthe
␈↓ ↓H␈↓most␈α⊂exceptional␈α⊂computer␈α⊂science␈α∂talents.␈α⊂ LISP␈α⊂does␈α⊂a␈α⊂lot␈α∂of␈α⊂things␈α⊂well.␈α⊂ As␈α⊂a␈α∂programming
␈↓ ↓H␈↓language,␈α⊗it␈α↔is␈α⊗an␈α⊗exceptional␈α↔tool␈α⊗for␈α⊗developing␈α↔sophisticated␈α⊗applications.␈α↔The␈α⊗artificial
␈↓ ↓H␈↓intelligence␈α∩community␈α∩has␈α∩always␈α⊃been␈α∩one␈α∩of␈α∩the␈α⊃most␈α∩demanding␈α∩and␈α∩creative␈α∩builders␈α⊃of
␈↓ ↓H␈↓programming tools. LISP's treatment of program and data supports this kind of behavior.
␈↓ ↓H␈↓Until␈α∞we␈α∞can␈α
develop␈α∞a␈α∞better␈α∞tool␈α
which␈α∞handles␈α∞any␈α
of␈α∞these␈α∞areas␈α∞as␈α
well␈α∞as␈α∞LISP,␈α∞LISP␈α
will
␈↓ ↓H␈↓survive.␈α
Indications␈αare␈α
that␈αwe␈α
may␈αhave␈α
learned␈αenough␈α
in␈αthe␈α
last␈αtwenty␈α
years␈αto␈α
build␈αa␈α
viable
␈↓ ↓H␈↓successor.
␈↓ ↓H␈↓␈↓↓386 Projects␈↓ C9.␈↓
␈↓ ↓H␈↓␈↓ ¬x␈↓↓CHAPTER 9
␈↓ ↓H␈↓↓␈↓ εPROJECTS␈↓
␈↓ ↓H␈↓This␈α
chapter␈α
consists␈α
of␈αa␈α
set␈α
of␈α
non-trivial␈αprojects␈α
which␈α
either␈α
apply␈αLISP␈α
or␈α
extend␈α
LISP␈αby
␈↓ ↓H␈↓adding new language features.
␈↓ ↓H␈↓␈↓ ¬<␈↓↓9.1 Extensions to ␈↓αeval␈↓↓␈↓α
␈↓ ↓H␈↓This␈α!next␈α!extension␈α to␈α!␈↓αeval␈↓␈α!was␈α!derived␈α from␈α!the␈α!syntax␈α!of␈α MUDDLE[Mud 75],
␈↓ ↓H␈↓CONNIVER[Con 73],␈α_and␈α_MICRO-PLANNER[Mic 71].␈α_ We␈α↔have␈α_seen␈α_that␈α_LISP␈α↔calling
␈↓ ↓H␈↓sequences␈α∩are␈α⊃of␈α∩two␈α∩varieties:␈α⊃either␈α∩evaluate␈α⊃␈↓↓all␈↓␈α∩of␈α∩the␈α⊃arguments;␈α∩or␈α⊃evaluate␈α∩␈↓↓none␈↓␈α∩of␈α⊃the
␈↓ ↓H␈↓arguments.
␈↓ ↓H␈↓In␈α∞an␈α
attempt␈α∞to␈α
generalize␈α∞this␈α
regime␈α∞we␈α
might␈α∞allow␈α
the␈α∞evaluation␈α
of␈α∞some␈α
of␈α∞the␈α
arguments
␈↓ ↓H␈↓and␈α⊂enlarge␈α⊂on␈α⊂the␈α⊂domain␈α⊂of␈α⊂objects␈α⊂which␈α∂can␈α⊂appear␈α⊂in␈α⊂the␈α⊂list␈α⊂of␈α⊂λ-variables.␈α⊂ We␈α∂might
␈↓ ↓H␈↓partition␈α∩the␈α∩formal␈α∪parameters␈α∩into␈α∩required␈α∩parameters,␈α∪optional␈α∩parameters,␈α∩and␈α∪an␈α∩excess
␈↓ ↓H␈↓collector␈αto␈αhandle␈αany␈αactual␈αparameters␈α
left␈αover.␈α Required␈αparameters␈α␈↓↓must␈↓␈αhave␈α
corresponding
␈↓ ↓H␈↓actual␈αparameters;␈αoptional␈αactual␈αparameters␈αare␈αused␈αif␈αpresent,␈αotherwise␈αdeclared␈αdefault␈αvalues
␈↓ ↓H␈↓are␈α⊂used.␈α⊃ If␈α⊂there␈α⊃are␈α⊂more␈α⊂actual␈α⊃parameters␈α⊂than␈α⊃the␈α⊂formals␈α⊂encompassed␈α⊃by␈α⊂the␈α⊃first␈α⊂two
␈↓ ↓H␈↓classes, then they are associated with the excess collector.
␈↓ ↓H␈↓To be more precise consider the following possible BNF equations:
␈↓ ↓H␈↓<varlist>␈↓ βλ::=[<required> <optional> <excess>]
␈↓ ↓H␈↓<required>␈↓ βλ::= <par>; ...;<par> | ␈↓ε␈↓ ␈↓π 245␈↓
␈↓ ↓H␈↓<optional>␈↓ βλ::= "optional" <opn>; ...; <opn> | ␈↓ε␈↓
␈↓ ↓H␈↓<excess>␈↓ βλ::= "excess" <par> | ␈↓ε␈↓
␈↓ ↓H␈↓<par>␈↓ βλ::= <variable> | ␈↓λ`␈↓<variable>
␈↓ ↓H␈↓<opn>␈↓ βλ::= <par> | <par> ← <form>
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 245␈↓ The symbol "␈↓ε␈↓" stands for the empty string.
␈↓ ↓H␈↓␈↓↓9.1␈↓ εExtensions to ␈↓αeval␈↓↓ 387␈↓α
␈↓ ↓H␈↓The associated semantics are as follows:
␈↓ ↓H␈↓␈↓↓1.␈↓ The formal parameters are to be bound to the actual parameters from left to right as usual.
␈↓ ↓H␈↓␈↓↓2.␈↓␈α⊂There␈α⊃must␈α⊂be␈α⊂an␈α⊃actual␈α⊂parameter␈α⊃for␈α⊂each␈α⊂required␈α⊃parameter,␈α⊂and␈α⊂if␈α⊃there␈α⊂is␈α⊃no␈α⊂excess
␈↓ ↓H␈↓␈↓ αhcollector␈α
there␈α
may␈α
not␈α
be␈α
more␈α
actual␈α
parameters␈α
than␈α
formals.␈α
(There␈α
may␈α
be␈α
fewer␈α
if
␈↓ ↓H␈↓␈↓ αhwe have optionals.)
␈↓ ↓H␈↓␈↓↓3.␈↓␈α⊃If␈α⊃a␈α⊃<variable>␈α⊃in␈α⊃a␈α⊃formal␈α⊃parameter␈α⊃is␈α⊃preceded␈α⊃by␈α⊃a␈α⊃"␈↓λ`␈↓",␈α⊃then␈α⊃the␈α⊃corresponding␈α⊃actual
␈↓ ↓H␈↓␈↓ αhparameter is ␈↓↓not␈↓ evaluated. This is just the ␈↓αquote␈↓-ing ␈↓αread␈↓ macro.
␈↓ ↓H␈↓␈↓↓4.␈↓␈αWe␈αmight␈αrun␈αout␈αof␈αactual␈αparameters␈α
while␈αbinding␈αthe␈αoptionals.␈α If␈αwe␈αdo,␈αthen␈αwe␈α
look␈αat
␈↓ ↓H␈↓␈↓ αhthe␈αremaining␈αformal␈αoptionals.␈α
If␈αa␈αformal␈αparameter␈αis␈α
simply␈αa␈α<par>␈αthen␈αwe␈α
bind
␈↓ ↓H␈↓␈↓ αhit␈α⊃to␈α⊂␈↓α( )␈↓;␈α⊃if␈α⊂a␈α⊃formal␈α⊂is␈α⊃␈↓λ`␈↓<variable>␈α⊂←␈α⊃<form>␈α⊂then␈α⊃we␈α⊂bind␈α⊃the␈α⊂<variable>␈α⊃to␈α⊂the
␈↓ ↓H␈↓␈↓ αh<form>;␈αand␈αif␈αthe␈αformal␈αis␈α<variable>␈α←␈α<form>,␈αwe␈αbind␈α<variable>␈αto␈αthe␈αvalue␈αof
␈↓ ↓H␈↓␈↓ αh<form>,␈αwhere␈αthe␈αevaluation␈αis␈αto␈αtake␈αplace␈α␈↓↓after␈↓␈αthe␈αrequired␈αparameters␈αhave␈αbeen
␈↓ ↓H␈↓␈↓ αhbound.
␈↓ ↓H␈↓␈↓↓5.␈↓␈αFinally,␈αthe␈αexcess␈αcollector␈αis␈αbound␈αto␈αa␈αlist␈αof␈αany␈αremaining␈αactual␈αparameters␈αin␈αthe␈αobvious
␈↓ ↓H␈↓␈↓ αhway:␈α⊂if␈α⊂<par>␈α⊂is␈α⊃<variable>␈α⊂then␈α⊂using␈α⊂the␈α⊂calling␈α⊃environment,␈α⊂form␈α⊂a␈α⊂list␈α⊃of␈α⊂the
␈↓ ↓H␈↓␈↓ αhvalues␈α
of␈α
the␈α
remaining␈α
arguments;␈α
if␈α
it␈α
is␈α
␈↓λ`␈↓<variable>,␈α
bind␈α
<variable>␈α
to␈α∞the␈α
actual
␈↓ ↓H␈↓␈↓ αhlist. If there is no excess, bind to ␈↓αNIL␈↓.
␈↓ ↓H␈↓We␈α∃will␈α∃also␈α∃extend␈α⊗␈↓αprog␈↓-variables␈α∃slightly,␈α∃allowing␈α∃them␈α⊗to␈α∃be␈α∃initialized␈α∃explicitly.␈α⊗If␈α∃a
␈↓ ↓H␈↓␈↓αprog␈↓-variable␈α∞is␈α
atomic,␈α∞intialize␈α
it␈α∞to␈α
␈↓α( )␈↓,␈α∞as␈α
usual.␈α∞If␈α
it␈α∞is␈α
of␈α∞the␈α
form␈α∞<variable> ← <form>␈α
then
␈↓ ↓H␈↓initialize it to the value of the <form>.
␈↓ ↓H␈↓Here are some examples:
␈↓ ↓H␈↓1. In the initialization of ␈↓αlength␈↓ on page 172, we could write: ␈↓α... prog[[l ← x; c ← 0] ....␈↓
␈↓ ↓H␈↓2. ␈↓αlist␈↓ could now be defined as: ␈↓αλ[[␈↓"excess"␈↓α x]x]␈↓.
␈↓ ↓H␈↓3. Consider the following definition:
␈↓ ↓H␈↓␈↓ αX␈↓αbaz <= λ[␈↓ βX[x;␈↓λ`␈↓αy;␈↓"optional"␈↓α z; u ← 0; ␈↓"excess"␈↓α v]
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[x];
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[y];
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[z];
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[u];
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[v] ].
␈↓ ↓H␈↓␈↓↓388 Projects␈↓ 79.1␈↓
␈↓ ↓H␈↓α␈↓Then a call of:
␈↓ ↓H␈↓␈↓ αa␈↓αeval[(BAZ 2 (CAR (QUOTE (X Y))) 4 5 6 7 (CAR (QUOTE (A . B))));NIL]␈↓
␈↓ ↓H␈↓would print:␈↓α␈↓ βX␈↓ βh2
␈↓ ↓H␈↓α␈↓ αX␈↓ βX(CAR(QUOTE (X Y)))
␈↓ ↓H␈↓α␈↓ αX␈↓ βX4
␈↓ ↓H␈↓α␈↓ αX␈↓ βX5
␈↓ ↓H␈↓α␈↓ αX␈↓ βX(6 7 A)␈↓
␈↓ ↓H␈↓and return value: ␈↓α(6 7 A)␈↓.
␈↓ ↓H␈↓Similarly, defining:
␈↓ ↓H␈↓␈↓ αX␈↓αfii <= λ[␈↓ βX[x;y;␈↓"optional"␈↓α z; u ← 0; ␈↓"excess"␈↓α v]
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[x];
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[y];
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[z];
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[u];
␈↓ ↓H␈↓α␈↓ αX␈↓ βXprint[v]].
␈↓ ↓H␈↓α␈↓and calling: ␈↓ ∧D␈↓αeval[(FII 2 (CAR (QUOTE (X Y)));NIL]␈↓
␈↓ ↓H␈↓αprints:␈↓ αX␈↓ βX2
␈↓ ↓H␈↓α␈↓ αX␈↓ βXX
␈↓ ↓H␈↓α␈↓ αX␈↓ βXNIL
␈↓ ↓H␈↓α␈↓ αX␈↓ βX0
␈↓ ↓H␈↓α␈↓ αX␈↓ βXNIL.
␈↓ ↓H␈↓␈↓ ε⊃␈↓↓Problems␈↓
␈↓ ↓H␈↓Design simple S-expr representations of these proposed constructs. Make these extensions to ␈↓αeval␈↓.
␈↓ ↓H␈↓␈↓ ¬M␈↓↓9.2 Pretty-printing␈↓
␈↓ ↓H␈↓This␈α_project␈α_expands␈α_on␈α_the␈α→basic␈α_notion␈α_of␈α_"pretty-printing"␈α_which␈α_was␈α→introduced␈α_on
␈↓ ↓H␈↓page 254␈↓π 246␈↓.␈α⊂The␈α⊃content␈α⊂of␈α⊂this␈α⊃section␈α⊂introduces␈α⊂several␈α⊃possible␈α⊂considerations␈α⊃involved␈α⊂in
␈↓ ↓H␈↓designing␈αasuch␈αa␈αpretty␈αprinter.␈αThe␈αintent␈αof␈αthis␈αsection␈αis␈αfor␈αyou␈αto␈αtake␈αthese␈αsuggestions␈αand
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 246␈↓ Pretty printers are called "grinders" at MIT.
␈↓ ↓H␈↓␈↓↓9.2␈↓ *Pretty-printing 389␈↓
␈↓ ↓H␈↓develop␈α∪a␈α∪suitable␈α∪program␈α∪based␈α∪on␈α∪the␈α∪suggestions␈α∪and␈α∪your␈α∪experience␈α∪with␈α∪your␈α∩locally
␈↓ ↓H␈↓available prettry printer. The formats described in this section were extracted form [Gol 73].
␈↓ ↓H␈↓I.␈α␈↓↓Linear␈αformat␈↓:␈αThe␈α
minimal␈αacceptable␈αoutput␈αformat␈α
is␈αthat␈αproduced␈αby␈α
␈↓αprint␈↓.␈α Acceptability
␈↓ ↓H␈↓is␈α
judged␈α
by␈α
whether␈α
that␈α
output␈α
can␈α
be␈αread␈α
back␈α
into␈α
the␈α
machine␈α
and␈α
have␈α
a␈α
structure␈α␈↓αequal␈↓␈α
the
␈↓ ↓H␈↓the structure printed out␈↓π 247␈↓.
␈↓ ↓H␈↓II.␈α
␈↓↓Standard␈α
format␈↓:␈αGiven␈α
a␈α
list␈α
␈↓α(␈↓εa␈αb␈α
c␈α
␈↓...␈↓ε␈α
d␈↓α)␈↓␈αthe␈α
standard␈α
format␈α
will␈αassume␈α
that␈α
we␈α
are␈αtrying␈α
to
␈↓ ↓H␈↓print a function application and will producce:
␈↓ ↓H␈↓␈↓ βx␈↓α(␈↓εa␈↓ ∧(b
␈↓ ↓H␈↓ε␈↓ βx␈↓ ∧(c
␈↓ ↓H␈↓ε␈↓ βx␈↓ ∧( ␈↓. . .␈↓ε
␈↓ ↓H␈↓ε␈↓ βx␈↓ ∧(d␈↓α)
␈↓ ↓H␈↓Thus ␈↓α(FOO (CAR (CONS (QUOTE A) B)) (G (H A) 4))␈↓ would produce:
␈↓ ↓H␈↓␈↓ βx␈↓α(FOO␈↓ ∧H(CAR (CONS␈↓ ελ(QUOTE A)
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧H␈↓ ∧x␈↓ ελB))
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧H(G␈↓ ∧x(H A)
␈↓ ↓H␈↓α␈↓ βx␈↓ ∧H␈↓ ∧x4))
␈↓ ↓H␈↓Note␈α⊂that␈α⊂the␈α∂"standard␈α⊂format"␈α⊂is␈α∂recursively␈α⊂applied,␈α⊂and␈α∂thus␈α⊂may␈α⊂become␈α∂too␈α⊂wide␈α⊂for␈α∂the
␈↓ ↓H␈↓output device. It that case we can resort to the following format.
␈↓ ↓H␈↓III. ␈↓↓Miser format␈↓: Write a list ␈↓α(␈↓εa b c ␈↓...␈↓ε d␈↓α)␈↓ as:
␈↓ ↓H␈↓␈↓ βx␈↓α(␈↓εa
␈↓ ↓H␈↓ε␈↓ βx b
␈↓ ↓H␈↓ε␈↓ βx c
␈↓ ↓H␈↓ε␈↓ βx ␈↓. . .␈↓ε
␈↓ ↓H␈↓ε␈↓ βx d␈↓α)
␈↓ ↓H␈↓Again,␈αthe␈αrecursive␈αapplication␈αof␈αthis␈αformat␈αcan␈αoverflow␈αthe␈αoutput␈αwidth.␈αIn␈αthat␈αcase␈αwe␈α
may
␈↓ ↓H␈↓have to resort to "linear format".
␈↓ ↓H␈↓________________
␈↓ ↓H␈↓␈↓π 247␈↓ We must hedge that a bit, since ␈↓αgensym␈↓ atoms are not placed on the object list.
␈↓ ↓H␈↓␈↓↓390 Projects␈↓ 59.2␈↓
␈↓ ↓H␈↓Typical␈αpretty␈αprinters␈αalso␈α
recognize␈αcertain␈αLISP␈αconstructs␈α
and␈α"grind"␈αthem␈αdifferently.␈αThat␈α
is,
␈↓ ↓H␈↓we␈α⊃build␈α⊃some␈α⊃semantic␈α⊃knowledge␈α⊃into␈α⊃the␈α⊂grinder.␈α⊃Block␈α⊃format␈α⊃is␈α⊃useful␈α⊃in␈α⊃many␈α⊃of␈α⊂these
␈↓ ↓H␈↓contexts.
␈↓ ↓H␈↓IV. ␈↓↓Block format␈↓: A list ␈↓α(␈↓εa␈↓β1␈↓ ... ␈↓εa␈↓βn-1␈↓, ... ␈↓εa␈↓βn␈↓α)␈↓ has the block format:
␈↓ ↓H␈↓␈↓ βx␈↓α(␈↓ ∧λ␈↓εa␈↓β1␈↓ ... ␈↓εa␈↓βn-1␈↓
␈↓ ↓H␈↓␈↓ βx␈↓ ∧λ␈↓εa␈↓βn␈↓ ... ␈↓εa␈↓βn␈↓α)␈↓
␈↓ ↓H␈↓For␈α
example,␈α
the␈α
list␈α
representation␈αof␈α
a␈α
␈↓αprog␈↓␈α
might␈α
be␈α"ground"␈α
with␈α
its␈α
␈↓αprog␈↓␈α
variables␈α
in␈αblock
␈↓ ↓H␈↓format␈α
and␈α
special␈α
indenting␈α
in␈α
the␈α
␈↓αprog␈↓ body␈αto␈α
set␈α
off␈α
the␈α
labels.␈α
The␈α
representation␈α
of␈α␈↓αlength␈↓
␈↓ ↓H␈↓given␈α⊂on␈α⊂page 178␈α⊃illustrates␈α⊂the␈α⊂special␈α⊃format␈α⊂for␈α⊂␈↓αprog␈↓s,␈α⊂though␈α⊃the␈α⊂␈↓αprog␈↓ variable␈α⊂list␈α⊃is␈α⊂not
␈↓ ↓H␈↓sufficently long to require block format.
␈↓ ↓H␈↓Another list format which is treated specially is the representation of a λ-expression.
␈↓ ↓H␈↓␈↓ βx␈↓α(LAMBDA␈↓ ¬(␈↓<λ-list ground in block format>
␈↓ ↓H␈↓␈↓ βx␈↓ ¬(<body ground as a block>␈↓α)
␈↓ ↓H␈↓The␈α
example␈α
on␈αpage 178␈α
also␈α
illistrates␈α
this.␈α This␈α
format␈α
will␈α
allow␈αmultiple-bodied␈α
λ-expressions.
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓α␈↓ βx(LAMBDA␈↓ ¬_(X Y Z)
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬_(CONS␈↓ ελX
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬_␈↓ ελ(QUOTE A))
␈↓ ↓H␈↓α␈↓ βx␈↓ ¬_(H 1 2))
␈↓ ↓H␈↓Notice␈αthat␈αwe␈αdecided␈αto␈αwrite␈α␈↓α(H␈α1␈α2)␈↓␈αin␈αlinear␈αformat␈αrather␈αthan␈αstandard␈αformat;␈αsomehow␈αit
␈↓ ↓H␈↓"looks␈α
better".␈α
Personal␈αtaste␈α
plays␈α
a␈αstrong␈α
role␈α
in␈αpretty␈α
printing,␈α
so␈αseveral␈α
grinders␈α
give␈αthe␈α
users
␈↓ ↓H␈↓the␈α∩ability␈α∩to␈α∩describe␈α∩their␈α∩own␈α∩formats.␈α∩We␈α∩will␈α∩see␈α∩a␈α∩similar,␈α∩but␈α∩more␈α∩general␈α∩device␈α⊃in
␈↓ ↓H␈↓Section 9.4.␈α⊗ Another␈α∃possibility␈α⊗for␈α∃user␈α⊗extension␈α∃lies␈α⊗with␈α∃our␈α⊗property␈α∃list␈α⊗evaluator␈α∃of
␈↓ ↓H␈↓Section 5.8.␈α Part␈αof␈αthe␈αdefinition␈αof␈αthe␈αvarious␈αLISP␈αconstructs␈αwould␈αallow␈αthe␈α
specification␈αof
␈↓ ↓H␈↓output␈α
conventions␈α∞for␈α
instances␈α∞of␈α
those␈α∞constructs;␈α
thus␈α∞besides␈α
specifying␈α∞evaluation␈α
properties
␈↓ ↓H␈↓for␈α␈↓αLAMBDA␈↓,␈α␈↓αPROG␈↓,␈αand␈α␈↓αCOND␈↓,␈αwe␈αwould␈αalso␈αthe␈αgrinding␈αroutines␈αfor␈αoutputting␈αinstances␈αof
␈↓ ↓H␈↓those constructs.
␈↓ ↓H␈↓Since␈α∪lists␈α∪beginning␈α∩with␈α∪␈↓αCOND␈↓␈α∪are␈α∩representations␈α∪of␈α∪conditional␈α∩expressions␈α∪they␈α∪too␈α∩are
␈↓ ↓H␈↓handled specially by the grinding routines.
␈↓ ↓H␈↓␈↓ βx␈↓α(COND␈↓␈↓ ∧h<grind clause␈↓β1␈↓>
␈↓ ↓H␈↓␈↓ βx␈↓ ∧h . . .
␈↓ ↓H␈↓␈↓ βx␈↓ ∧h<grind clause␈↓βn␈↓>␈↓α)
␈↓ ↓H␈↓These␈α
selected␈α
formats␈α
should␈αgive␈α
a␈α
reasonable␈α
idea␈α
of␈αthe␈α
techniques␈α
available␈α
for␈αpretty␈α
printers.
␈↓ ↓H␈↓More techniques can be extracted from your local grinder.
␈↓ ↓H␈↓␈↓↓9.2␈↓ *Pretty-printing 391␈↓
␈↓ ↓H␈↓Your␈αpretty␈α
printer␈αmay␈α
assume␈αthe␈αexistence␈α
of␈α␈↓αpatom␈↓,␈α
␈↓αprint␈↓,␈αand␈α␈↓αterpri␈↓␈α
of␈αSection 5.11;␈α
and␈αyou
␈↓ ↓H␈↓may␈α∂assume␈α∂the␈α∂existence␈α∂of␈α∂the␈α∂usual␈α∂class␈α∂of␈α∂arithmetic␈α∂operations.␈α∂In␈α∂addition,␈α⊂the␈α∂following
␈↓ ↓H␈↓formatting primitives may be used:
␈↓ ↓H␈↓␈↓↓1.␈↓␈α␈↓αlinelength␈↓:␈αIf␈α␈↓αlinelength␈↓␈αis␈αcalled␈αwithout␈αan␈αargument␈αthen␈αthe␈αvalue␈αreturned␈αis␈αthe␈αnumber␈αof
␈↓ ↓H␈↓␈↓ αhcharacters␈αallowed␈αon␈αa␈αline␈αof␈αthe␈αcurrent␈αoutput␈αdevice.␈αIf␈α␈↓αlinelength␈↓␈αis␈αcalled␈αwith␈αa
␈↓ ↓H␈↓␈↓ αhnumeric argument, then the line length of the output device is set to that number.
␈↓ ↓H␈↓␈↓↓2.␈↓␈α∞␈↓αchrct␈↓:␈α∞This␈α∞is␈α∂a␈α∞nullary␈α∞function,␈α∞and␈α∞returns␈α∂a␈α∞number␈α∞representing␈α∞the␈α∞number␈α∂of␈α∞character
␈↓ ↓H␈↓␈↓ α8positions␈αremaining␈αon␈αthe␈αcurrent␈αline.␈αFor␈αexample,␈αjust␈αafter␈α␈↓αterpri[]␈↓␈αhas␈αbeen␈αexecuted
␈↓ ↓H␈↓␈↓ α8␈↓αchrct[] = linelength[]␈↓, and ␈↓αprog␈↓β2␈↓α[patom[ABC]; difference[linelength[];chrct[]]] = 3␈↓.
␈↓ ↓H␈↓␈↓↓3.␈↓␈α⊂␈↓αflatsize␈↓:␈α⊂A␈α∂simple␈α⊂count␈α⊂of␈α∂the␈α⊂atoms␈α⊂and␈α∂special␈α⊂characters␈α⊂in␈α∂an␈α⊂expression␈α⊂won't␈α⊂give␈α∂an
␈↓ ↓H␈↓␈↓ αhaccurate␈α
picture␈α
of␈α
the␈α
requirements␈α
for␈α
printing␈α
an␈α
expression.␈α
Special␈α
characters␈α
take
␈↓ ↓H␈↓␈↓ αhone␈αcharacter␈αposition,␈αbut␈αliteral␈αatoms␈αand␈αnumbers␈αmay␈αrequire␈αmore.␈αTo␈αdetermine
␈↓ ↓H␈↓␈↓ αhwhether␈α
or␈α
not␈α
a␈αspecial␈α
format␈α
can␈α
be␈α
used␈αon␈α
an␈α
expression␈α
requires␈α
knowledge␈αof␈α
its
␈↓ ↓H␈↓␈↓ αhcharacter␈α∩count.␈α∩The␈α∩number␈α∩of␈α∩characters␈α∩in␈α∩the␈α∩atom␈α∩␈↓αx␈↓␈α∩is␈α∩given␈α∩by␈α∩␈↓αflatsize[x]␈↓;
␈↓ ↓H␈↓␈↓ αh␈↓αflatsize[ABCD]␈↓␈α
is␈α
␈↓α4␈↓.␈α
Actually␈α
␈↓αflatsize␈↓␈α
is␈α
defined␈α
for␈α
non-atomic␈α
arguments,␈α∞giving␈α
the
␈↓ ↓H␈↓␈↓ αhnumber␈α≠of␈α≠character␈α≠positions␈α≠required␈α≠to␈α≠␈↓αprint␈↓␈α≠its␈α≠argument.␈α≠For␈α≠example
␈↓ ↓H␈↓␈↓ αh␈↓αflatsize[(A.B)]␈↓ is ␈↓α7␈↓ rather than ␈↓α5␈↓ since ␈↓αprint␈↓ will surround the dot with spaces.
␈↓ ↓H␈↓␈↓ ¬λ␈↓↓9.3 Syntax-directed Processes␈↓
␈↓ ↓H␈↓We␈α∀should␈α∀now␈α∪have␈α∀sufficient␈α∀background␈α∀to␈α∪examine␈α∀reasonably␈α∀complex␈α∀and␈α∪non-trivial
␈↓ ↓H␈↓problems.␈α∪ This␈α∩project␈α∪is␈α∩an␈α∪introduction␈α∩to␈α∪the␈α∩very␈α∪important␈α∩area␈α∪called␈α∩␈↓↓syntax-directed
␈↓ ↓H␈↓↓processes␈↓.␈α⊃ Syntax-directed␈α⊃techniques␈α∩are␈α⊃used␈α⊃extensively␈α∩in␈α⊃compiler␈α⊃construction.␈α∩ We␈α⊃shall
␈↓ ↓H␈↓begin by applying these techniques to evaluation.
␈↓ ↓H␈↓As␈αwe␈αsaid␈αearlier␈αthere␈α
are␈αalternatives␈αto␈αthe␈αcall-by-value␈α
evaluation␈αscheme;␈αand␈αas␈αwe␈αall␈α
know
␈↓ ↓H␈↓there are alternatives to the prefix notation which we chose to represent function application.
␈↓ ↓H␈↓For␈αexample,␈αin␈αgrade␈αschool␈αwe␈αall␈α
learned␈αinfix␈αnotation␈αand␈αits␈αimplied␈αprecedence␈αrelations,␈α
say
␈↓ ↓H␈↓for␈α+␈αand␈α*.␈αSimply␈αbecause␈αinfix␈αnotation␈αis␈αthe␈αfirst␈αrepresentation␈αwe␈αsee␈αdoesn't␈αmean␈αthat␈αit␈αis
␈↓ ↓H␈↓the most convenient for evaluation either by us or by machine.
␈↓ ↓H␈↓Let's␈αtake␈αas␈αexample␈αthe␈αexpression:␈α2+3*5.␈α The␈αgrade␈αschool␈αprecedence␈αrelations␈αsay␈αthat␈α*␈α
takes
␈↓ ↓H␈↓precedence␈α∂over␈α∂+.␈α∂ That␈α∂is,␈α∂the␈α∂expression␈α∂represents␈α∂2+(3*5)␈α∂rather␈α∂than␈α∂(2+3)*5.␈α∂ We␈α∂can␈α∂also
␈↓ ↓H␈↓easily␈α
write␈α
the␈α
expression␈α
in␈α
prefix␈αnotation:␈α
+[2;*[3;5]].␈α
Here␈α
the␈α
precedence␈α
of␈α
operations␈αis␈α
made
␈↓ ↓H␈↓explicit.␈α
Similarly,␈αpostfix␈α
notation␈α
(where␈αthe␈α
operators␈αfollow␈α
rather␈α
than␈αprecede␈α
the␈αoperands)␈α
is
␈↓ ↓H␈↓easy: [2;[3;5]*]+.
␈↓ ↓H␈↓␈↓↓392 Projects␈↓ 59.3␈↓
␈↓ ↓H␈↓Why␈α↔this␈α↔preoccupation␈α_with␈α↔notation?␈α↔Well,␈α↔some␈α_notational␈α↔schemes␈α↔lend␈α_themselves␈α↔to
␈↓ ↓H␈↓mechanical␈α∪evaluation␈α∪better␈α∪than␈α∪others.␈α∪ There␈α∪is␈α∪a␈α∪certain␈α∪amount␈α∪of␈α∪implied␈α∪intelligence
␈↓ ↓H␈↓required␈α∩in␈α∩the␈α∩usual␈α⊃infix␈α∩scheme.␈α∩ We␈α∩have␈α∩already␈α⊃seen␈α∩one␈α∩very␈α∩mechanical␈α∩method␈α⊃for
␈↓ ↓H␈↓evaluating some prefix expressions: the ␈↓αvalue␈↓ function in Section 2.6.
␈↓ ↓H␈↓Consider␈αthe␈αpostfix␈αnotation.␈αWe␈αwill␈αfirst␈αclaim␈αthat␈αsince␈αwe␈αknow␈αthat␈αplus␈αand␈αtimes␈αare␈αboth
␈↓ ↓H␈↓binary␈αoperations,␈αthe␈αpunctuation,␈α ], [,␈αand␈α; , ␈αis␈αredundant␈α(this␈αis␈αalso␈αtrue␈αfor␈αprefix␈αnotation).
␈↓ ↓H␈↓Thus the string, 2 3 5 * +, contains the same information as [2;[3;5]*]+.
␈↓ ↓H␈↓A␈αstrong␈αpoint␈αof␈αpostfix␈αstring␈α
notation␈αis␈αits␈αease␈αof␈αevaluation.␈α
Using␈α"↓"␈αto␈αpoint␈αto␈αthe␈α
current
␈↓ ↓H␈↓position␈αin␈αthe␈α
string␈αand␈αusing␈α
the␈α"| ... |"-notation␈αof␈α
page 110␈αto␈αrepresent␈α
the␈αstack,␈αthe␈α
following
␈↓ ↓H␈↓is a trace of the evaluation of the above string, 2 3 5 * +.
␈↓ ↓H␈↓↓ ↓ ↓
␈↓ ↓H␈↓2 3 5 * + ;| | => 3 5 * + ;| 2 | => 5 * + ;␈↓ ε_| 3 | =>
␈↓ ↓H␈↓␈↓ β(␈↓ ε_| 2 |
␈↓ ↓H␈↓↓ ↓
␈↓ ↓H␈↓* + ; | 5 | => + ;␈↓ β(| 15 | => | 17 |.
␈↓ ↓H␈↓ | 3 |␈↓ β(| 2 |
␈↓ ↓H␈↓ | 2 |
␈↓ ↓H␈↓It␈α∞is␈α∞a␈α∞very␈α∞simple␈α∞task␈α∞to␈α∞program␈α∞this␈α∞scheme␈α∞as␈α∞a␈α∞LISP␈α∞␈↓αprog␈↓.␈α∞ Similarly,␈α∞it␈α∞is␈α∞quite␈α∞simple␈α∞to
␈↓ ↓H␈↓extend this evaluation scheme to n-ary operators.
␈↓ ↓H␈↓Given␈α∞an␈α∂arbitrary␈α∞arithmetic␈α∂expression␈α∞involving␈α∞constants,␈α∂and␈α∞the␈α∂binary␈α∞operations␈α∂of␈α∞plus
␈↓ ↓H␈↓and␈α
times,␈α
we␈αhave␈α
a␈α
straightforward␈α
mechanical␈αevaluation␈α
scheme.␈α
It␈αis␈α
intuitively␈α
clear␈α
how␈αto
␈↓ ↓H␈↓translate␈αinfix␈αexpressions␈αinto␈α
postfix␈αnotation.␈α If␈αwe␈αcould␈α
mechanize␈αthis␈αprocess␈αthen␈αwe␈α
would
␈↓ ↓H␈↓have␈αan␈α
algorithm␈αfor␈αthe␈α
evaluation␈αof␈αinfix␈α
expressions.␈α First␈αlet's␈α
attempt␈αto␈α
describe␈αprecisely
␈↓ ↓H␈↓the␈α∂class␈α∂of␈α∂infix␈α∂expressions␈α∂which␈α∂we␈α∂wish␈α∂to␈α∂evaluate.␈α∂The␈α∂BNF␈α∂notation␈α∂is␈α∂a␈α∂good␈α∞vehicle.
␈↓ ↓H␈↓Perhaps the following:
␈↓ ↓H␈↓␈↓ βx<exp>␈↓ ∧x::= <exp><binop><exp>
␈↓ ↓H␈↓␈↓ βx␈↓ ∧x::= <integer>
␈↓ ↓H␈↓␈↓ βx<binop>␈↓ ∧x::= + | * .
␈↓ ↓H␈↓There␈αare␈αmany␈αthings␈αwrong␈αwith␈αthis␈αattempt␈αat␈αa␈αgrammar.␈α First,␈αmany␈αexpressions␈αhave␈αmore
␈↓ ↓H␈↓than␈α∞one␈α∂possible␈α∞description␈α∂or␈α∞parse␈α∂tree␈α∞(the␈α∂grammar␈α∞is␈α∂said␈α∞to␈α∂be␈α∞ambiguous).␈α∂Second,␈α∞this
␈↓ ↓H␈↓grammar doesn't express our usual precedence relations. The next attempt is successful:
␈↓ ↓H␈↓␈↓↓9.3␈↓ λ!Syntax-directed Processes 393␈↓
␈↓ ↓H␈↓␈↓ βx<exp>␈↓ ¬(::= <exp> + <term>␈↓ λH(1)
␈↓ ↓H␈↓␈↓ βx␈↓ ¬(::= <term>␈↓ λH(2)
␈↓ ↓H␈↓␈↓ βx<term>␈↓ ¬(::= <term> * <factor>␈↓ λH(3)
␈↓ ↓H␈↓␈↓ βx␈↓ ¬(::= <factor>␈↓ λH(4)
␈↓ ↓H␈↓␈↓ βx<factor>␈↓ ¬(::= ( <exp> )␈↓ λH(5)
␈↓ ↓H␈↓␈↓ βx␈↓ ¬(::= <integer>␈↓ λH(6)
␈↓ ↓H␈↓␈↓ βx<integer>␈↓ ¬(::= 0 | 1 | 2 ....␈↓ λH(7)
␈↓ ↓H␈↓For example the (only) parsing of 2+3*5 is:
␈↓ ↓H␈↓ <exp>
␈↓ ↓H␈↓ |
␈↓ ↓H␈↓ <exp> + <term>
␈↓ ↓H␈↓ | |
␈↓ ↓H␈↓ <term> <term>*<factor>
␈↓ ↓H␈↓ | | |
␈↓ ↓H␈↓ <factor> <factor> <integer>
␈↓ ↓H␈↓ | | |
␈↓ ↓H␈↓ <integer> <integer> 5
␈↓ ↓H␈↓ | |
␈↓ ↓H␈↓ 2 3
␈↓ ↓H␈↓Our next step is based on the following:
␈↓ ↓H␈↓Assumption:␈αGiven␈α
an␈αarbitrary␈α
(well-formed)␈αarithmetic␈α
expression,␈αe,␈α
of␈αour␈α
above␈αclass,␈α
we␈αcan
␈↓ ↓H␈↓␈↓ αhfind␈αthe␈α
left-most␈αwell-formed␈α
subexpression,␈αs,␈α
such␈αthat␈αs␈α
is␈αan␈α
instance␈αof␈α
the␈αRHS
␈↓ ↓H␈↓␈↓ αhof␈αone␈α
of␈αthe␈αrules,␈α
(1)-(7).␈αLet␈α
e␈↓λ'␈↓␈αbe␈αthe␈α
expression␈αobtained␈αfrom␈α
e,␈αby␈α
replacing␈αthe
␈↓ ↓H␈↓␈↓ αhoccurrence of the RHS by the LHS; then our assumption is also applicable to e␈↓λ'␈↓.
␈↓ ↓H␈↓␈↓↓394 Projects␈↓ 59.3␈↓
␈↓ ↓H␈↓For example,
␈↓ ↓H␈↓␈↓ αλe␈↓ ∧hs␈↓ πλe␈↓λ'␈↓␈↓ Xrule
␈↓ ↓H␈↓␈↓ αλ 2+3*5␈↓ ∧h 2␈↓ πλ<integer>+3*5␈↓ X(7)
␈↓ ↓H␈↓␈↓ αλ<integer>+3*5␈↓ ∧h<integer>␈↓ πλ<factor>+3*5␈↓ X(6)
␈↓ ↓H␈↓␈↓ αλ<factor>+3*5␈↓ ∧h<factor>␈↓ πλ<term>+3*5␈↓ X(4)
␈↓ ↓H␈↓␈↓ αλ<term>+3*5␈↓ ∧h<term>␈↓ πλ<exp>+3*5␈↓ X(2)
␈↓ ↓H␈↓␈↓ αλ<exp>+3*5␈↓ ∧h3␈↓ πλ<exp>+<integer>*5␈↓ X(7)
␈↓ ↓H␈↓␈↓ αλ<exp>+<integer>*5␈↓ ∧h<integer>␈↓ πλ<exp>+<factor>*5␈↓ X(6)
␈↓ ↓H␈↓␈↓ αλ<exp>+<factor>*5␈↓ ∧h<factor>␈↓ πλ<exp>+<term>*5␈↓ X(4)
␈↓ ↓H␈↓␈↓ αλ<exp>+<term>*5␈↓ ∧h5␈↓ πλ<exp>+<term>*<integer>␈↓ X(7)
␈↓ ↓H␈↓␈↓ αλ<exp>+<term>*<integer>␈↓ ∧h<integer>␈↓ πλ<exp>+<term>*<factor>␈↓ X(6)
␈↓ ↓H␈↓␈↓ αλ<exp>+<term>*<factor>␈↓ ∧h<term>*<factor>␈↓ πλ<exp>+<term>␈↓ X(3)
␈↓ ↓H␈↓␈↓ αλ<exp>+<term>␈↓ ∧h<exp>+<term>␈↓ πλ<exp>␈↓ X(1)
␈↓ ↓H␈↓Let␈α
us␈α
now␈αassociate␈α
an␈α
action␈αwith␈α
each␈α
of␈αthe␈α
rules␈α
(1)-(7)␈αsuch␈α
that␈α
whenever␈αwe␈α
apply␈α
one␈αof
␈↓ ↓H␈↓the␈αrules␈αin␈αthe␈αabove␈αreduction␈αtechnique,␈α
we␈αwill␈αalso␈αexecute␈αthe␈αcorresponding␈αaction.␈α
We␈αwill
␈↓ ↓H␈↓also designate an initialization routine which will be executed at the beginning of the reduction.
␈↓ ↓H␈↓Initialization:␈αLet␈αV[0:N]␈αbe␈αa␈αvector␈αindexed␈αfrom␈α0␈αto␈αN,␈αwhere␈αN␈αis␈αat␈αleast␈αas␈αlong␈αas␈αthe␈α
input
␈↓ ↓H␈↓character string. Let i be an integer variable, initialized to 0.
␈↓ ↓H␈↓␈↓ αλ rule␈↓ β8␈↓ ¬h action
␈↓ ↓H␈↓␈↓ αλ<exp>␈↓ β8::= <exp> + <term>␈↓ ¬hV(i) ← `+'; i ← i+1
␈↓ ↓H␈↓␈↓ αλ␈↓ β8::= <term>␈↓ ¬h do nothing
␈↓ ↓H␈↓␈↓ αλ<term>␈↓ β8::= <term>*<factor>␈↓ ¬hV(i) ← `*'; i ← i+1
␈↓ ↓H␈↓␈↓ αλ␈↓ β8::= <factor>␈↓ ¬h do nothing
␈↓ ↓H␈↓␈↓ αλ<factor>␈↓ β8::= (<exp>)␈↓ ¬h do nothing
␈↓ ↓H␈↓␈↓ αλ␈↓ β8::= <integer>␈↓ ¬h do nothing
␈↓ ↓H␈↓␈↓ αλ<integer>␈↓ β8::= 0 | 1 | ...␈↓ ¬hV(i) ← 0 | V(i) ← 1 | ... ; i ← i+1
␈↓ ↓H␈↓␈↓↓9.3␈↓ λ!Syntax-directed Processes 395␈↓
␈↓ ↓H␈↓Again␈αperforming␈αthe␈αreduction␈αof␈αthe␈αexpression,␈α2+3*5,␈αbut␈αnow␈αexecuting␈αthe␈αaction␈αroutines␈αas
␈↓ ↓H␈↓well we find the contents of V will contain the following:
␈↓ ↓H␈↓ V: 0 1 2 3 4
␈↓ ↓H␈↓ 2
␈↓ ↓H␈↓ 2 3
␈↓ ↓H␈↓ 2 3 5
␈↓ ↓H␈↓ 2 3 5 *
␈↓ ↓H␈↓ 2 3 5 * +
␈↓ ↓H␈↓That is, the postfix form of the arithmetic expression is formed in V.
␈↓ ↓H␈↓So␈α⊂combining␈α⊂the␈α⊂two␈α⊂algorithms,␈α∂(1) infix␈α⊂to␈α⊂postfix␈α⊂translation,␈α⊂and (2) postfix␈α⊂evaluation,␈α∂we
␈↓ ↓H␈↓could␈α
write␈α
an␈α
infix␈α
evaluator.␈α
However,␈α
we␈α
can␈α∞go␈α
one␈α
better.␈α
By␈α
a␈α
simple␈α
change␈α
to␈α∞the␈α
action
␈↓ ↓H␈↓routines we can perform infix evaluation as we reduce (or recognize) the expression.
␈↓ ↓H␈↓Initialization: Let V[0:N] be a vector and let i be an integer-valued variable, initialized to 0.
␈↓ ↓H␈↓␈↓ αλ rule␈↓ β8␈↓ ¬h action
␈↓ ↓H␈↓␈↓ αλ<exp>␈↓ β8::= <exp>+<term>␈↓ ¬hV(i-2) ← V(i-1)+V(i-2); i ← i-1
␈↓ ↓H␈↓␈↓ αλ␈↓ β8::= <term>␈↓ ¬h do nothing
␈↓ ↓H␈↓␈↓ αλ<term>␈↓ β8::= <term>*<factor>␈↓ ¬hV(i-2) ← V(i-1)*V(i-2); i ← i-1
␈↓ ↓H␈↓␈↓ αλ␈↓ β8::= <factor>␈↓ ¬h do nothing
␈↓ ↓H␈↓␈↓ αλ<factor>␈↓ β8::= (<exp>)␈↓ ¬h do nothing
␈↓ ↓H␈↓␈↓ αλ␈↓ β8::= <integer>␈↓ ¬h do nothing
␈↓ ↓H␈↓␈↓ αλ<integer>␈↓ β8::= 0 | 1 | ...␈↓ ¬hV(i) ← 0 | V(i) ← 1| ... ; i ← i+1
␈↓ ↓H␈↓When␈α
the␈α
arithmetic␈α
expression␈α
has␈α
been␈α
recognized,␈α
V(0)␈α
will␈α
contain␈α
the␈α
value␈α
of␈α
that␈α
expression.
␈↓ ↓H␈↓Notice␈αthat␈αthe␈αcombination␈αof␈αV␈αand␈αits␈αindex␈αi,␈αis␈αperforming␈αas␈αa␈αstack␈αin␈αthis␈αtranslator.␈αThat
␈↓ ↓H␈↓is:␈αwhen␈αwe␈αsee␈αan␈αinteger,␈αwe␈αpush␈αit␈α
into␈αthe␈αstack;␈αwhen␈αwe␈αsee␈αa␈α(binary)␈αoperator␈αwe␈α
pop␈αthe
␈↓ ↓H␈↓two operands, perform the operation and push the result back on the stack.
␈↓ ↓H␈↓This␈α⊃technique␈α⊂of␈α⊃associating␈α⊃action␈α⊂routines␈α⊃(also␈α⊂called␈α⊃semantic␈α⊃routines)␈α⊂with␈α⊃the␈α⊃BNF␈α⊂(or
␈↓ ↓H␈↓syntax)␈α∩equations␈α⊃is␈α∩extremely␈α⊃powerful.␈α∩ Such␈α⊃processes␈α∩are␈α⊃called␈α∩syntax-directed.␈α∩ When␈α⊃we
␈↓ ↓H␈↓discuss compilation syntax-directed methods will be used.
␈↓ ↓H␈↓␈↓↓396 Projects␈↓ 59.3␈↓
␈↓ ↓H␈↓␈↓ ε∨␈↓↓Project␈↓
␈↓ ↓H␈↓Write␈αa␈αLISP␈αprogram␈αto␈αperform␈αinfix␈αto␈αpostfix␈αtranslation;␈αand␈αthen␈αmodify␈αit␈αto␈αperform␈αinfix
␈↓ ↓H␈↓evaluation.␈αWrite␈αyour␈αprograms␈αtwo␈αways:␈αfirst␈αuse␈αan␈αexplicit␈αstack;␈αthen␈αuse␈αrecursion␈αto␈αoperate
␈↓ ↓H␈↓with an implicit stack.
␈↓ ↓H␈↓␈↓ ε∨␈↓↓Project␈↓
␈↓ ↓H␈↓As␈αa␈αfurther␈αexample␈α
of␈αsyntax-directed␈αprocesses␈αrecall␈αthe␈α
set␈αof␈αexpressions␈αevaluated␈αby␈α
␈↓αtgmoaf␈↓:
␈↓ ↓H␈↓the␈α⊃five␈α⊂primitives␈α⊃under␈α⊂composition␈α⊃of␈α⊂functions,␈α⊃all␈α⊂with␈α⊃constant␈α⊂arguments.␈α⊃ Write␈α⊂syntax
␈↓ ↓H␈↓equations and action routines to effect the evaluation of such expressions.
␈↓ ↓H␈↓␈↓ ¬-␈↓↓9.4 Syntax-directed I/O␈↓
␈↓ ↓H␈↓It␈α
is␈α
frequently␈αquite␈α
desirable␈α
and␈α
convenient␈αto␈α
enter␈α
input␈α
and␈αreceive␈α
output␈α
in␈αsomething␈α
other
␈↓ ↓H␈↓than␈α∪S-exprs.␈α∪ Recall␈α∪our␈α∀diagram␈α∪on␈α∪page 52.␈α∪ ␈↓αeval␈↓␈α∪demonstrated␈α∀that␈α∪at␈α∪least␈α∪one␈α∀style␈α∪of
␈↓ ↓H␈↓evaluation␈αcan␈αbe␈α
mechanized.␈α What␈αwe␈α
wish␈αto␈αdo␈α
now␈αis␈αexamine␈α
the␈αpossibility␈αof␈α
mechanizing
␈↓ ↓H␈↓the encoding of the input and the decoding of the output.
␈↓ ↓H␈↓Consider␈α∀for␈α∃example,␈α∀the␈α∀problem␈α∃of␈α∀simplification␈α∀of␈α∃algebraic␈α∀expressions.␈α∃ Many␈α∀rather
␈↓ ↓H␈↓sophisticated␈αsimplifiers␈α
have␈αbeen␈α
written␈α([Hea 68],␈α[MAC 74]).␈α
Assume␈αthat␈α
we␈αhave␈αone␈α
named
␈↓ ↓H␈↓␈↓αsimplify␈↓ which expects S-expr input and gives S-expr output. Thus for example:
␈↓ ↓H␈↓α␈↓ α¬(3+4)*x + x =␈↓βI ␈↓α=> (PLUS (TIMES (PLUS 3 4) X) X) =␈↓βsimplify␈↓α=> (TIMES 8 X) =␈↓βO ␈↓α=> 8*x.
␈↓ ↓H␈↓We␈α∞would␈α∂like␈α∞transformations␈α∂I␈α∞and␈α∂O␈α∞done␈α∞automatically.␈α∂M-expr␈α∞notation␈α∂is␈α∞a␈α∂candidate␈α∞for
␈↓ ↓H␈↓such a task.
␈↓ ↓H␈↓α␈↓ αXcons[A;B] =␈↓βI ␈↓α=> (CONS (QUOTE A)(QUOTE B)) =␈↓βeval␈↓α=> (A . B) =␈↓βO ␈↓α=> (A . B)
␈↓ ↓H␈↓Transformation O is the identity in this case.
␈↓ ↓H␈↓In␈α⊂many␈α⊂cases␈α⊃the␈α⊂automatic␈α⊂generation␈α⊃of␈α⊂the␈α⊂I␈α⊃and␈α⊂O␈α⊂transformations␈α⊃can␈α⊂be␈α⊂done.␈α⊃Such␈α⊂a
␈↓ ↓H␈↓program,␈α∞SDIO␈α∞(Syntax Directed Input Output),␈α∞was␈α∞written␈α∞by␈α∞Lynn␈α∞Quam␈α∞of␈α∞the␈α∂Stanford␈α∞AI
␈↓ ↓H␈↓Laboratory␈α≠in␈α≤1968␈α≠[Qua 68].␈α≤It␈α≠was␈α≠the␈α≤forerunner␈α≠of␈α≤the␈α≠more␈α≤ambitious␈α≠MLISP2
␈↓ ↓H␈↓project[Mli 73].␈α
The␈α
basic␈α
idea␈αis␈α
simple␈α
enough.␈α
We␈α
will␈αassume␈α
that␈α
the␈α
input␈α
and␈αoutput␈α
syntax
␈↓ ↓H␈↓is␈α∞specified␈α∞in␈α∞BNF.␈α∂With␈α∞each␈α∞BNF␈α∞equation␈α∞we␈α∂will␈α∞associate␈α∞semantics␈α∞describing␈α∂the␈α∞S-expr
␈↓ ↓H␈↓representation.␈α→The␈α→input␈α→transformation␈α→(parser)␈α~will␈α→use␈α→this␈α→information␈α→to␈α~build␈α→the
␈↓ ↓H␈↓representation; and the output transformation (unparser) will map the internal representation back.
␈↓ ↓H␈↓␈↓↓9.4␈↓ λnSyntax-directed I/O 397␈↓
␈↓ ↓H␈↓The␈α⊂importance␈α⊃of␈α⊂syntax␈α⊃directed␈α⊂I/O␈α⊃should␈α⊂not␈α⊃be␈α⊂minimized.␈α⊃One␈α⊂aspect␈α⊃of␈α⊂SDIO␈α⊃is␈α⊂the
␈↓ ↓H␈↓ablility␈αto␈αdefine␈α
new␈αdata␈αtypes␈α
in␈αLISP.␈αAssume␈αwe␈α
wish␈αto␈αrepresent␈α
a␈αstructure␈αas␈αa␈α
particularly
␈↓ ↓H␈↓horrible␈α≠list␈α≠structure.␈α≠We␈α≠can␈α≠give␈α≠augmented␈α≠BNF␈α≠equations␈α≠specifying␈α≠the␈α~external
␈↓ ↓H␈↓representation␈α
and␈αthe␈α
translation␈αto␈α
the␈αunderlying␈α
representation.␈αClearly␈α
when␈α
outputting␈αthese
␈↓ ↓H␈↓structures␈α∂we␈α∂do␈α∂not␈α⊂want␈α∂to␈α∂see␈α∂the␈α∂internal␈α⊂representation.␈α∂This␈α∂can␈α∂be␈α⊂particularly␈α∂annoying
␈↓ ↓H␈↓when␈αwe␈αare␈αdebugging;␈αwhen␈αwe␈αare␈αtrying␈αto␈αconcentrate␈αon␈αa␈αmisbehaving␈αalgorithm␈αwe␈αdo␈αnot
␈↓ ↓H␈↓want␈αto␈α
be␈αdistracted␈αby␈α
incomprehensible␈αoutput.␈α Thus␈α
syntax␈αdirected␈αoutput,␈α
or␈αunparsing,␈αis␈α
at
␈↓ ↓H␈↓least as important as input.
␈↓ ↓H␈↓Perhaps␈α∩the␈α∪easiest␈α∩introduction␈α∪to␈α∩SDIO␈α∪is␈α∩to␈α∪examine␈α∩an␈α∪example.␈α∩Consider␈α∪the␈α∩proposed
␈↓ ↓H␈↓simplification␈α
task␈α∞above.␈α
The␈α
"natural"␈α∞input␈α
syntax␈α
can␈α∞be␈α
described␈α
in␈α∞BNF.␈α
We␈α∞have␈α
given
␈↓ ↓H␈↓closely␈αrelated␈αsyntax␈αequations␈αon␈αpage 393.␈αWe␈αwill␈αdisplay␈αa␈αfew␈αequations␈αaugmented␈αby␈αSDIO
␈↓ ↓H␈↓semantics.
␈↓ ↓H␈↓For example:
␈↓ ↓H␈↓ <EXP>␈↓ βH::= <EXP> + <TERM>␈↓ λ(=>(PLUS EXP TERM)
␈↓ ↓H␈↓␈↓ βH::= <TERM>␈↓ λ(=>*
␈↓ ↓H␈↓ <TERM>␈↓ βH::= <NUMBER>␈↓ λ(=>*
␈↓ ↓H␈↓To␈α∞the␈α∞input␈α∞parser␈α∞the␈α∞first␈α∞BNF␈α∞equation␈α∞means:␈α∞whenever␈α∞the␈α∞right␈α∞hand␈α∞side␈α∞is␈α
recognized,
␈↓ ↓H␈↓reduce␈α∞that␈α∞occurrence␈α∞to␈α∞the␈α∞left␈α∞hand␈α∞side␈α∞and␈α∞associate␈α∞with␈α∞it␈α∞the␈α∞list␈α∞consisting␈α∞of␈α∂the␈α∞atom
␈↓ ↓H␈↓PLUS,␈α∞the␈α∞S-expr␈α∞associated␈α∞with␈α∞the␈α∂occurrence␈α∞of␈α∞<EXP>,␈α∞and␈α∞the␈α∞S-expr␈α∞associated␈α∂with␈α∞the
␈↓ ↓H␈↓occurrrence␈α⊂of␈α⊃<TERM>.␈α⊂ The␈α⊃second␈α⊂equation␈α⊃means␈α⊂reduce␈α⊃<TERM>␈α⊂to␈α⊃<EXP>␈α⊂associating
␈↓ ↓H␈↓whatever␈αS-expr␈αis␈αattached␈αto␈α<TERM>␈αwith␈αthat␈αoccurrence␈αof␈α<EXP>.␈αIn␈αthe␈αthird␈αequation␈α
we
␈↓ ↓H␈↓assume␈αthat␈α<NUMBER>␈αis␈αa␈αsyntactic␈αtype␈αrecognized␈αby␈αthe␈αscanner,␈αand␈αreturn␈αthat␈αnumber␈αas
␈↓ ↓H␈↓the␈α⊂semantic␈α⊂value.␈α⊂ For␈α∂example,␈α⊂if␈α⊂such␈α⊂a␈α∂parser␈α⊂were␈α⊂given␈α⊂2+3+44␈α∂it␈α⊂should␈α⊂return␈α⊂the␈α∂list
␈↓ ↓H␈↓␈↓α(PLUS (PLUS 2 3) 44)␈↓.
␈↓ ↓H␈↓The␈αunparser␈αuses␈α
these␈αequations␈αin␈α
the␈αinverse␈αmanner.␈αIt␈α
will␈αsee␈αa␈α
S-expr␈αand␈αwill␈α
attempt␈αto
␈↓ ↓H␈↓match that to the description of the semantics, outputting an instance of the BNF if successful.
␈↓ ↓H␈↓The␈αSDIO␈αprogram␈αwill␈αtake␈αsuch␈αan␈αaugmented␈αset␈αof␈αBNF␈αequations␈αand␈αgenerate␈αa␈αparser␈αand
␈↓ ↓H␈↓an␈αunparser␈αfor␈αthe␈αlanguage.␈α This␈αproject␈α
involves␈αwriting␈αsuch␈αa␈αSDIO␈αprogram.␈αWe␈αdescribe␈α
a
␈↓ ↓H␈↓basic SDIO program and suggest extensions and improvements.
␈↓ ↓H␈↓The best way to describe the format of SDIO input is to give an SDIO description.
␈↓ ↓H␈↓␈↓↓398 Projects␈↓ 29.4␈↓
␈↓ ↓H␈↓<RULES>␈↓ βH::= END␈↓ λ(=>NIL
␈↓ ↓H␈↓␈↓ βH::=<RULE><RULES>␈↓ λ(=>(RULE . RULES)
␈↓ ↓H␈↓<RULE>␈↓ βH::= <LFPT><RTLST>␈↓ λ(=>(LFPT RTLST)
␈↓ ↓H␈↓<RTLST>␈↓ βH::= ::=<RTPT><SEXPR><RTLST>␈↓ λ(=>((RTPT SEXPR) . RTLST)
␈↓ ↓H␈↓␈↓ βH::= ␈↓ε␈↓␈↓ λ(=>NIL
␈↓ ↓H␈↓<LFPT>␈↓ βH::= <<ID>>␈↓ λ(=>*
␈↓ ↓H␈↓<RTPT>␈↓ βH::= "=>␈↓ λ(=>NIL
␈↓ ↓H␈↓␈↓ βH::= <RPELEM><RTPT>␈↓ λ(=>(RPELEM . RTPT)
␈↓ ↓H␈↓<RPELEM>␈↓ βH::= <<ID>>␈↓ λ(=>*
␈↓ ↓H␈↓␈↓ βH::= <ID>␈↓ λ(=>(SPWD ID)
␈↓ ↓H␈↓␈↓ βH::= ""<CHAR>␈↓ λ(=>(QCH CHAR)
␈↓ ↓H␈↓␈↓ βH::= <CHAR>␈↓ λ(=>(CH CHAR)
␈↓ ↓H␈↓<SEXPR>␈↓ βH::= <ATOM>␈↓ λ(=>*
␈↓ ↓H␈↓␈↓ βH::= (<SEXPRLIST>)␈↓ λ(=>*
␈↓ ↓H␈↓<SEXPRLIST>␈↓ βH::= <ATOM>␈↓ λ(=>*
␈↓ ↓H␈↓␈↓ βH::= <SEXPR> <SEXPRLIST>␈↓ λ(=>(SEXPR . SEXPRLIST)
␈↓ ↓H␈↓␈↓ βH::= ␈↓ε␈↓␈↓ λ(=>NIL
␈↓ ↓H␈↓END
␈↓ ↓H␈↓The␈αexpressions␈α␈↓α(SPWD␈αID),␈α(QCH␈αCHAR),␈↓␈αand␈α␈↓α(CH␈αCHAR)␈↓␈αare␈αS-expr␈αrepresentations␈αof␈αcalls
␈↓ ↓H␈↓on␈α⊗rountines␈α⊗to␈α⊗process␈α⊗special␈α⊗or␈α⊗reserved␈α⊗words,␈α⊗quoted␈α⊗characters␈α⊗or␈α⊗special␈α∃characters,
␈↓ ↓H␈↓respectively.
␈↓ ↓H␈↓The␈αinput␈αto␈αSDIO␈αis␈αa␈αsequence␈αof␈αaugmented␈αBNF␈αequations␈αterminated␈αwith␈αEND.␈α What␈αthe
␈↓ ↓H␈↓SDIO␈α
program␈α
sees␈α
is␈α
a␈α
S-expr␈α
representation␈α
of␈α
these␈α
equations.␈α
The␈α
sample␈α
equations␈α
for␈α
<EXP>
␈↓ ↓H␈↓above would pass the following to the SDIO program:
␈↓ ↓H␈↓␈↓ αX(␈↓ βλ(EXP (␈↓ ∧λ((EXP (CH +) TERM) (PLUS EXP TERM))
␈↓ ↓H␈↓␈↓ αX␈↓ βλ␈↓ ∧λ((TERM) NIL)))
␈↓ ↓H␈↓␈↓ αX␈↓ βλ(TERM (␈↓ ∧λ((NUMBER) NIL))) )
␈↓ ↓H␈↓What the SDIO program outputs are the parser and unparser.
␈↓ ↓H␈↓The␈α∞elements␈α
of␈α∞the␈α∞BNF␈α
equations␈α∞in␈α∞SDIO␈α
are␈α∞rather␈α∞standard:␈α
syntactic␈α∞variables,␈α∞which␈α
are
␈↓ ↓H␈↓identifiers␈α
bracketed␈α
by␈α
"<"␈α
and␈α
">";␈α
and␈α
special␈α
words,␈α
which␈α
are␈α
identifiers;␈α
and␈αspecial␈α
characters,
␈↓ ↓H␈↓which are preceeded by " if they conflict with the special characters of the BNF.
␈↓ ↓H␈↓␈↓↓9.4␈↓ λnSyntax-directed I/O 399␈↓
␈↓ ↓H␈↓The␈α∞elements␈α∂of␈α∞the␈α∞semantics␈α∂are:␈α∞unbracketed␈α∞syntactic␈α∂variables␈α∞occurring␈α∞in␈α∂the␈α∞RHS␈α∂of␈α∞the
␈↓ ↓H␈↓associated␈α∞BNF␈α∞equation;␈α∞other␈α∞identifiers,␈α∞taken␈α∂as␈α∞constants;␈α∞NIL,␈α∞the␈α∞LISP␈α∞atom;␈α∂notation␈α∞for
␈↓ ↓H␈↓␈↓αcons␈↓-ing, ␈↓α( . )␈↓; notation for making a list, ␈↓α(e␈↓β1␈↓α ... e␈↓βn␈↓α)␈↓; the character *, described above.
␈↓ ↓H␈↓␈↓ ε∨␈↓↓Project␈↓
␈↓ ↓H␈↓Write␈α∂such␈α∂a␈α∂SDIO␈α∂program.␈α∂You␈α∂should␈α∂consult␈α∂local␈α∂LISP␈α∂documentation␈α∂when␈α∂building␈α∞the
␈↓ ↓H␈↓basic I/O routines like <NUMBER>, <CHAR>, or <ID>.
␈↓ ↓H␈↓␈↓ ¬h␈↓↓First Extension␈↓
␈↓ ↓H␈↓You␈αmay␈αhave␈α
noticed␈αalready␈αthat␈αthe␈α
basic␈αSDIO␈αprogram␈αfails␈α
to␈αdistinguish␈αtwo␈αoccurrences␈α
of
␈↓ ↓H␈↓the same syntactic variable on the RHS of an equation. Thus an equation like:
␈↓ ↓H␈↓<ZIP>␈↓ α8::= <ZAP> <FOO> <ZAP> must be replaced by the pair:
␈↓ ↓H␈↓<ZIP>␈↓ α8::= <ZAP> <FOO> <ZAP1>
␈↓ ↓H␈↓<ZAP1>␈↓ α8::=<ZAP>
␈↓ ↓H␈↓This trick is called stratification. It is a syntactic trick, adding nothing to the semantics.
␈↓ ↓H␈↓Add␈αnotation␈αto␈αthe␈αsemantics␈αof␈αyour␈αSDIO␈αprogram␈αto␈αhandle␈αRHS␈αwith␈αmultiple␈αoccurrences␈αof
␈↓ ↓H␈↓syntactic variables. Modify your parser generators accordingly.
␈↓ ↓H␈↓␈↓ ¬Y␈↓↓Second Extension␈↓
␈↓ ↓H␈↓Besides␈α
building␈α
a␈α∞S-expr␈α
representation␈α
of␈α∞the␈α
input,␈α
it␈α
is␈α∞frequently␈α
desirable␈α
to␈α∞generate␈α
other
␈↓ ↓H␈↓information␈αduring␈αthe␈αinput␈αparse.␈αLists␈αof␈αoccurrences␈αof␈αoperators␈αor␈αother␈αtables␈αare␈αcommonly
␈↓ ↓H␈↓needed.␈α∂The␈α∞additional␈α∂information␈α∞could␈α∂be␈α∞discovered␈α∂by␈α∞examination␈α∂of␈α∞the␈α∂completed␈α∞parse
␈↓ ↓H␈↓tree,␈α
but␈α
that␈α
requires␈α
reexamination␈α
of␈α
the␈α
tree.␈αIt␈α
is␈α
much␈α
more␈α
efficient␈α
to␈α
do␈α
as␈α
much␈αas␈α
possible
␈↓ ↓H␈↓on a single pass.
␈↓ ↓H␈↓Introduce␈αnotation␈αwhich␈αwill␈αallow␈αexecution␈αof␈αarbitrary␈αLISP␈αcode␈αas␈αthe␈αparse␈αprogresses.␈α
That
␈↓ ↓H␈↓code␈α⊂should␈α⊂be␈α∂able␈α⊂to␈α⊂manipulate␈α⊂any␈α∂of␈α⊂the␈α⊂semantic␈α∂properties␈α⊂associated␈α⊂with␈α⊂the␈α∂syntactic
␈↓ ↓H␈↓variables appearing in the RHS of the associated syntax equation.
␈↓ ↓H␈↓␈↓↓400 Projects␈↓ 29.4␈↓
␈↓ ↓H␈↓␈↓ ¬d␈↓↓Third extension␈↓
␈↓ ↓H␈↓While␈α⊃it␈α⊂is␈α⊃obviously␈α⊂advantageous␈α⊃to␈α⊃produce␈α⊂output␈α⊃in␈α⊂the␈α⊃language␈α⊂described␈α⊃by␈α⊃the␈α⊂BNF
␈↓ ↓H␈↓equations␈α∂rather␈α∂than␈α∞the␈α∂S-expr␈α∂form,␈α∂formatting␈α∞of␈α∂the␈α∂output␈α∞can␈α∂be␈α∂equally␈α∂beneficial.␈α∞ We
␈↓ ↓H␈↓should␈αlike␈αto␈αbe␈αable␈αto␈αspecify␈αformatting␈αinformation␈αin␈αSDIO␈αsuch␈αthat␈αspacing␈αand␈α
line-length
␈↓ ↓H␈↓are controlled.
␈↓ ↓H␈↓One␈α⊂proposal␈α∂is␈α⊂to␈α∂embed␈α⊂spacing␈α∂and␈α⊂line-feed␈α∂control␈α⊂characters␈α∂in␈α⊂the␈α∂BNF␈α⊂equations.␈α∂The
␈↓ ↓H␈↓spacing␈α
character␈α
is␈α
"→"␈α
and␈α
the␈α
line-feed␈α
is␈α
"↓".␈α
The␈α
"↑"␈α
sets␈α
the␈α
indentation␈α
point␈α
for␈α
the␈α
string␈α
on
␈↓ ↓H␈↓its␈α∂right;␈α∂and␈α∂the␈α∂"→"␈α∂followed␈α∂by␈α∂a␈α∂digit␈α∂says␈α∂space␈α∂over␈α∂than␈α∂number␈α∂of␈α∂spaces␈α∂from␈α⊂the␈α∂last
␈↓ ↓H␈↓indentation␈αpoint␈αif␈αthe␈αremaining␈α
space␈αon␈αthe␈αline␈αis␈αnot␈α
sufficient␈αto␈αcontain␈αall␈αtext␈αspecified␈α
by
␈↓ ↓H␈↓the remaining RHS of the equation. "0→", meaning go to the indentation point can be written "→".
␈↓ ↓H␈↓For example consider the following:
␈↓ ↓H␈↓␈↓ αX<EXPR>␈↓ ∧8::= <ID>( ↓ <EXPR_LIST>)
␈↓ ↓H␈↓␈↓ αX␈↓ ∧8::= <ID>
␈↓ ↓H␈↓␈↓ αX<EXPR_LIST>␈↓ ∧8::= ↑<EXPR> , →<EXPR_LIST>
␈↓ ↓H␈↓␈↓ αX␈↓ ∧8::= ↑<EXPR>
␈↓ ↓H␈↓These equations, when used to drive an unparser, could give:
␈↓ ↓H␈↓αmumf(␈↓ α(a,
␈↓ ↓H␈↓α␈↓ α(foobaz(garp(b)),
␈↓ ↓H␈↓α␈↓ α(bletch(a,b,c),
␈↓ ↓H␈↓α␈↓ α(d)
␈↓ ↓H␈↓as the formatted version of:
␈↓ ↓H␈↓α␈↓ ∧amumf(a,foobaz(garp(b)),bletch(a,b,c),d)
␈↓ ↓H␈↓Extend SDIO to handle formatting of output.
␈↓ ↓H␈↓␈↓↓10.␈↓
BIBLIOGRPAHY 401␈↓
␈↓ ↓H␈↓␈↓ ¬SBIBLIOGRAPHY␈↓α
␈↓ ↓H␈↓The basic form of an entry consists of three items:
␈↓ ↓H␈↓␈↓ α_␈↓↓1.␈↓ A short name which is how the document is referenced in the text.
␈↓ ↓H␈↓␈↓ α_␈↓↓2.␈↓ The full bibliographical reference.
␈↓ ↓H␈↓␈↓ α_␈↓↓3.␈↓␈α∂A␈α∂sequence␈α⊂of␈α∂pages␈α∂in␈α⊂the␈α∂text␈α∂which␈α∂refer␈α⊂to␈α∂this␈α∂document.␈α⊂If␈α∂the␈α∂document␈α⊂is␈α∂not
␈↓ ↓H␈↓␈↓ α_referenced␈α∂the␈α∂statement␈α∂␈↓↓[ norefs ]␈↓␈α∂appears␈α∞instead;␈α∂these␈α∂documents,␈α∂while␈α∂not␈α∞referenced,
␈↓ ↓H␈↓␈↓ α_are relevant to the material covered in the text.
␈↓ ↓H␈↓[Aho 72]␈↓ αxAho,␈α
A.,␈α∞and␈α
Ullman,␈α
J.,␈α∞␈↓αThe␈α
Theory␈α
of␈α∞Parsing,␈α
Translation␈α
&␈α∞Compiling␈↓,␈α
Prentice
␈↓ ↓H␈↓␈↓ βλHall Inc., Englewood Cliffs, N.J., 1972. ␈↓↓[␈↓␈↓↓ 4␈↓␈↓↓ 150␈↓␈↓↓ 285␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Alg 63]␈↓ αxNaur,␈α≠P.␈α≠et.␈α≠al.,␈α≠`Revised␈α≠Report␈α≠on␈α≠the␈α≠Algorithmic␈α≠Language␈α≠Algol␈α~60',
␈↓ ↓H␈↓␈↓ βλ␈↓αComm. ACM 6␈↓, ␈↓↓1␈↓, Jan., 1963. ␈↓↓[␈↓␈↓↓ 149␈↓␈↓↓ 339␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Alg 75]␈↓ αxvan␈α⊃Wijngaarden,␈α∩A.,␈α⊃et.␈α∩al.,␈α⊃eds.,␈α∩`Revised␈α⊃Report␈α∩on␈α⊃the␈α∩Algorithmic␈α⊃Language
␈↓ ↓H␈↓␈↓ βλAlgol 68', ␈↓αActa Informatica␈↓, Vol. 5, Fac. 1-3, p. 1-236, 1975. ␈↓↓[␈↓␈↓↓ 148␈↓␈↓↓ 261␈↓␈↓↓ 339␈↓␈↓↓ 358␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ama 72]␈↓ αxAmarel,␈α⊂S.,␈α⊂`A␈α⊂Set␈α⊂of␈α⊂Goals␈α∂and␈α⊂Approaches␈α⊂for␈α⊂Education␈α⊂in␈α⊂Computer␈α∂Science',
␈↓ ↓H␈↓␈↓ βλAFIPS Conference Proceedings, Vol 40, p. 841-846, 1972. ␈↓↓[␈↓␈↓↓ 143␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[And 76a]␈↓ αxAnderson,␈α⊃D.␈α⊂Bruce,␈α⊃`The␈α⊂Samefringe␈α⊃Problem',␈α⊂␈↓αSIGART␈α⊃Newsletter␈↓,␈α⊃No. 60,␈α⊂p. 4,
␈↓ ↓H␈↓␈↓ βλNov. 1976. ␈↓↓[␈↓␈↓↓ 209␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[And 76]␈↓ αxAnderson,␈α∂D.␈α⊂Bruce,␈α∂`A␈α⊂Brief␈α∂Critique␈α⊂of␈α∂LISP',␈α⊂Proc.␈α∂AISB␈α⊂Summer␈α∂Conference,
␈↓ ↓H␈↓␈↓ βλEdinburgh, p. 14-25, 1976. ␈↓↓[␈↓␈↓↓ 215␈↓␈↓↓ 361␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bac 73]␈↓ αxBackus,␈α∂J.,␈α∂`Programming␈α⊂Language␈α∂Semantics␈α∂and␈α∂Closed␈α⊂Applicative␈α∂Languages',
␈↓ ↓H␈↓␈↓ βλIBM Research Lab, RJ-1245, San Jose, Cal., July 1973. ␈↓↓[␈↓␈↓↓ 142␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bar 66]␈↓ αxBarron,␈α
D.,␈αand␈α
Strachey,␈α
C.,␈α`Programming',␈α
in␈α␈↓αAdvances␈α
in␈α
Computer␈αProgramming
␈↓ ↓H␈↓α␈↓ βλand␈α
Non-numerical␈α∞Computation␈↓,␈α
L. Fox,␈α
ed.,␈α∞Academic␈α
Press,␈α
New␈α∞York,␈α
p. 49-82,
␈↓ ↓H␈↓␈↓ βλ1966. ␈↓↓[␈↓␈↓↓ 182␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bar 71]␈↓ αxBarbacci,␈α∂M.,␈α∂et␈α∂al.,␈α∂`C.ai (P.LISP),␈α∂A␈α∂LISP␈α∂processor␈α∂of␈α∂C.ai',␈α⊂Carnegie-Mellon␈α∂U.,
␈↓ ↓H␈↓␈↓ βλ1971. ␈↓↓[␈↓␈↓↓ 223␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bau 72]␈↓ αxBaumgart,␈α∂B.,␈α∞`MICRO-PLANNER␈α∂Alternative␈α∞Reference␈α∂Manual',␈α∂Stanford␈α∞Univ.
␈↓ ↓H␈↓␈↓ βλOperating Note No. 67, April 1972. ␈↓↓[␈↓␈↓↓ 66␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓402 BIBLIOGRAPHY␈↓ 710.␈↓
␈↓ ↓H␈↓[Ber 64]␈↓ αxBerkeley,␈α
E.,␈α
and␈αBobrow,␈α
D.,␈α
eds.,␈α␈↓αThe␈α
Programming␈α
Language␈α
LISP: Its␈αOperation
␈↓ ↓H␈↓α␈↓ βλand Applications␈↓, Information International, Cambridge, Mass., 1964. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ber 71]␈↓ αxBerkling,␈α⊃H.,␈α⊃`A␈α⊃Computing␈α⊃Machine␈α⊂Based␈α⊃on␈α⊃Tree␈α⊃Structures',␈α⊃␈↓αIEEE␈α⊃Trans␈α⊂on
␈↓ ↓H␈↓α␈↓ βλComptr.␈↓ 20, C-20, ␈↓↓4␈↓, p. 404-418, April 1971. ␈↓↓[␈↓␈↓↓ 228␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Berr 71]␈↓ αxBerry,␈α∃D.,␈α⊗`Block␈α∃Structure: Retention␈α⊗or␈α∃Deletion?',␈α∃Proc.␈α⊗of␈α∃3␈↓πrd␈↓␈α⊗Annual␈α∃ACM
␈↓ ↓H␈↓␈↓ βλSymposium on Theory of Computing, p. 86-100, 1971. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bis 74a]␈↓ αxBishop,␈α⊃P.,␈α⊃`Garbage␈α⊃Collection␈α⊃in␈α⊃a␈α⊃Very␈α⊃Large␈α⊃Address␈α⊃Space',␈α⊂M.I.T. A.I. Lab,
␈↓ ↓H␈↓␈↓ βλWorking paper 111, Sep. 1975. ␈↓↓[␈↓␈↓↓ 377␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bis 74]␈↓ αxBishop, P., `Spaghetti Stacks', unpublished paper, M.I.T., Dec 19, 1974. ␈↓↓[␈↓␈↓↓ 271␈↓␈↓↓ 291␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bla 71]␈↓ αxBlair, F., `The Structure of the Lisp Compiler', unpublished paper, 1971. ␈↓↓[␈↓␈↓↓ 205␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bob 67]␈↓ αxBobrow,␈α⊃D.,␈α⊃and␈α⊃Murphy,␈α⊃D.,␈α⊃`The␈α⊃Structure␈α⊃of␈α⊃a␈α⊃LISP␈α⊃System␈α⊃Using␈α⊂Two-level
␈↓ ↓H␈↓␈↓ βλStorage', ␈↓αComm. ACM 10␈↓, ␈↓↓3␈↓, p. 155-159, Mar. 1967. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bob 69]␈↓ αxBobrow,␈α~D.,␈α~`(LISP␈α~Bulletin)',␈α→␈↓αACM␈α~Sigplan␈α~Notices␈↓,␈α~Vol. 1,␈α~No. 9,␈α→p. 17-45,
␈↓ ↓H␈↓␈↓ βλSept. 1969. ␈↓↓[␈↓␈↓↓ 180␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bob 73a]␈↓ αxBobrow,␈α∩D.,␈α∪and␈α∩Wegbreit,␈α∪B.,␈α∩`A␈α∪Model␈α∩and␈α∪Stack␈α∩Implementation␈α∪of␈α∩Multiple
␈↓ ↓H␈↓␈↓ βλEnvironments', ␈↓αComm. ACM 16␈↓, ␈↓↓10␈↓, p. 591-603, Oct. 1973. ␈↓↓[␈↓␈↓↓ 215␈↓␈↓↓ 280␈↓␈↓↓ 336␈↓␈↓↓ 377␈↓␈↓↓ 379␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bob 74]␈↓ αxBobrow,␈α∪D.,␈α∪and␈α∩Raphael,␈α∪D.,␈α∪`New␈α∩Programming␈α∪Languages␈α∪for␈α∪A.I.␈α∩Research',
␈↓ ↓H␈↓␈↓ βλ␈↓αComputing Surveys, 6␈↓, ␈↓↓3␈↓, p. 154-174, Sep 1974. ␈↓↓[␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bob 75]␈↓ αxBobrow,␈α"D.,␈α"`A␈α"Note␈α#on␈α"Hash␈α"Linking',␈α"␈↓αComm. ACM 18␈↓,␈α#␈↓↓7␈↓,␈α"p. 413-414,
␈↓ ↓H␈↓␈↓ βλJuly, 1975. ␈↓↓[␈↓␈↓↓ 378␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Boy 75]␈↓ αxBoyer,␈α∂R.,␈α∂and␈α∂Moore,␈α∂J,␈α⊂`Proving␈α∂theorems␈α∂about␈α∂LISP␈α∂functions',␈α⊂␈↓αJour. ACM ␈↓,␈α∂␈↓↓1␈↓,
␈↓ ↓H␈↓␈↓ βλp. 129-144, Mar. 1975. ␈↓↓[␈↓␈↓↓ 87␈↓␈↓↓ 145␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Bur 76]␈↓ αxBurge,␈α∪W.,␈α∪␈↓αRecursive␈α∪Programming␈α∪Techniques␈↓,␈α∪Addison␈α∪Wesley,␈α∪Reading,␈α∪Mass.,
␈↓ ↓H␈↓␈↓ βλ1976. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Car 76]␈↓ αxCartwright,␈α∀R.,␈α∀`A␈α∀Practical␈α∀and␈α∪Formal␈α∀Semantics␈α∀and␈α∀Verification␈α∀System␈α∪for
␈↓ ↓H␈↓␈↓ βλTYPED␈α$LISP',␈α$Ph.D. Thesis,␈α%Computer␈α$Science␈α$Dept.,␈α%Stanford␈α$Univ.,
␈↓ ↓H␈↓␈↓ βλ1976. ␈↓↓[␈↓␈↓↓ 87␈↓␈↓↓ 145␈↓␈↓↓ 224␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Che 67]␈↓ αxCheatham,␈α↔T.,␈α↔␈↓αThe␈α↔Theory␈α↔&␈α↔Construction␈α↔of␈α↔Compilers␈↓,␈α_Computer␈α↔Associates,
␈↓ ↓H␈↓␈↓ βλWakefield, Mass., 1967. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Che 70]␈↓ αxCheney,␈α→C.,␈α_`A␈α→Nonrecursive␈α_List␈α→Compacting␈α_Algorithm',␈α→␈↓αComm. ACM 13␈↓,␈α_␈↓↓11␈↓,
␈↓ ↓H␈↓␈↓ βλp. 677-678, Nov. 1970. ␈↓↓[␈↓␈↓↓ 376␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓10.␈↓
BIBLIOGRPAHY 403␈↓
␈↓ ↓H␈↓[Che 76]␈↓ αxCheatham,␈αT.,␈α
and␈αTownley,␈αJ.,␈α
`A␈αLook␈αat␈α
Programming␈αand␈αProgramming␈α
Systems',
␈↓ ↓H␈↓␈↓ βλin␈α⊂␈↓αAdvances␈α⊂in␈α⊂Computers␈↓,␈α⊂Vol.␈α⊂14,␈α⊂M.␈α⊂Rubinoff,␈α⊂and␈α⊂M.␈α⊂Yovits,␈α⊃eds.,␈α⊂Academic
␈↓ ↓H␈↓␈↓ βλPress, New York, p. 45-78, 1976. ␈↓↓[␈↓␈↓↓ 385␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Chr 68]␈↓ αxChristensen,␈α∃C.,␈α∃`An␈α∀Example␈α∃of␈α∃the␈α∃Manipulation␈α∀of␈α∃Directed␈α∃Graphs␈α∃in␈α∀the
␈↓ ↓H␈↓␈↓ βλAMBIT/G␈α#Programming␈α#Language',␈α#423-435,␈α#in␈α#␈↓αInteractive␈α#Systems␈α"for
␈↓ ↓H␈↓α␈↓ βλExperimental␈αApplied␈αMathematics␈↓,␈αKlerer,␈αM.,␈α&␈αReinfelds,␈αJ.␈αeds.,␈αAcademic␈αPress,
␈↓ ↓H␈↓␈↓ βλ1968. ␈↓↓[␈↓␈↓↓ 373␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Chu 41]␈↓ αxChurch,␈α⊗A.,␈α∃␈↓αThe␈α⊗Calculi␈α∃of␈α⊗Lambda-conversion␈↓,␈α∃Annals␈α⊗of␈α⊗Mathematics␈α∃Studies,
␈↓ ↓H␈↓␈↓ βλPrinceton University Press, New Jersey, 1941. ␈↓↓[␈↓␈↓↓ 98␈↓␈↓↓ 152␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Cl 76]␈↓ αxClark,␈α∂D.,␈α∂`List␈α∂Structure:␈α∂Measurements,␈α∂Algorithms␈α∂and␈α∂Encodings',␈α∂Ph.D.␈α∂Thesis,
␈↓ ↓H␈↓␈↓ βλCarnegie Mellon University, August 1976. ␈↓↓[␈↓␈↓↓ 354␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Cla 76]␈↓ αx376 ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Con 73]␈↓ αxMcDermott,␈α∀D.,␈α∀and␈α∪Sussman,␈α∀G.,␈α∀`The␈α∪CONNIVER␈α∀Reference␈α∀Manual',␈α∪M.I.T.
␈↓ ↓H␈↓␈↓ βλA.I. Lab. Memo 259a, Cambridge, Mass., 1973. ␈↓↓[␈↓␈↓↓ 68␈↓␈↓↓ 205␈↓␈↓↓ 215␈↓␈↓↓ 280␈↓␈↓↓ 384␈↓␈↓↓ 385␈↓␈↓↓ 386␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Con 74]␈↓ αxConrad,␈α
W.,␈α`A␈α
Compactifying␈α
Garbage␈αCollector␈α
for␈α
ECL's␈αNon-homogeneous␈α
Heap',
␈↓ ↓H␈↓␈↓ βλCenter␈α*for␈α+Research␈α*in␈α+Computing␈α*Technology,␈α+TR. 2-74,␈α*Harvard,
␈↓ ↓H␈↓␈↓ βλFeb. 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Dar 73]␈↓ αxDarlington,␈α
J.,␈αand␈α
Burstall,␈α
R.,␈α`A␈α
System␈αwhich␈α
Automatically␈α
Improves␈αPrograms',
␈↓ ↓H␈↓␈↓ βλProc. 3␈↓πrd␈↓ Int. J. Conf. on A.I., Stanford, 1973. ␈↓↓[␈↓␈↓↓ 145␈↓␈↓↓ 335␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Dav 76]␈↓ αxDavis,␈α∞R.,␈α∞`Deduction,␈α∞Truth,␈α
and␈α∞Computation',␈α∞M.S. Thesis,␈α∞Math. Dept.,␈α∞San␈α
Jose
␈↓ ↓H␈↓␈↓ βλState University, 1976. ␈↓↓[␈↓␈↓↓ 148␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[DEC 69]␈↓ αx`PDP-10␈α
Systems␈αReference␈α
Manual',␈α
Digital␈αEquipment␈α
Corporation,␈αMaynard␈α
Mass.,
␈↓ ↓H␈↓␈↓ βλ1969. ␈↓↓[␈↓␈↓↓ 290␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Deu 73]␈↓ αxDeutsch,␈αP.,␈α`A␈αLISP␈αMachine␈αWith␈αVery␈αCompact␈αPrograms',␈αProc.␈α3␈↓πrd␈↓␈αInt.␈αJ.␈αConf.
␈↓ ↓H␈↓␈↓ βλon A.I., Stanford, 1973. ␈↓↓[␈↓␈↓↓ 223␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Dif 71]␈↓ αxDiffie,␈α
W.,␈α
`Documentation␈α
of␈α∞the␈α
Compiler',␈α
unpublished␈α
paper,␈α
Stanford␈α∞A.I.␈α
Lab.,
␈↓ ↓H␈↓␈↓ βλ1971. ␈↓↓[␈↓␈↓↓ 245␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Dij 72a]␈↓ αxDijkstra,␈αE.,␈α`The␈αHumble␈αProgrammer:␈α1972␈αACM␈αTuring␈αLecture',␈α␈↓αComm. ACM␈α15␈↓,
␈↓ ↓H␈↓␈↓ βλ␈↓↓10␈↓, p. 859-866, Oct 1972. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Dij 72]␈↓ αxDijkstra,␈α∞E.,␈α∂`Notes␈α∞on␈α∂Structured␈α∞Programming',␈α∂in␈α∞␈↓αStructured␈α∂Programming␈↓,␈α∞Dahl,
␈↓ ↓H␈↓␈↓ βλO., and Hoare, C., eds., Academic Press, New York, 1972. ␈↓↓[␈↓␈↓↓ 50␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓404 BIBLIOGRAPHY␈↓ 710.␈↓
␈↓ ↓H␈↓[Dor 76]␈↓ αxDoran,␈α
R.,␈α
␈↓αArchitecture␈α
of␈α
General␈α
Purpose␈α
Computers␈↓,␈α
to␈α
be␈α
published␈α
by␈αAcademic
␈↓ ↓H␈↓␈↓ βλPress, New York. ␈↓↓[␈↓␈↓↓ 222␈↓␈↓↓ 295␈↓␈↓↓ 349␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[DSIPL]␈↓ αxProceedings␈α↔of␈α↔a␈α↔Symposium␈α↔on␈α↔Data␈α↔Structures␈α↔in␈α↔Programming␈α⊗Languages,
␈↓ ↓H␈↓␈↓ βλ␈↓αSIGPLAN Notices 6␈↓, ␈↓↓2␈↓, Feb. 1971. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[EL1 74]␈↓ αxWegbreit,␈α∃B.,␈α∃`ECL␈α∃Programmer's␈α⊗Manual',␈α∃Center␈α∃for␈α∃Research␈α⊗in␈α∃Computing
␈↓ ↓H␈↓␈↓ βλTechnology, TR 23-74, Harvard, Dec. 1974. ␈↓↓[␈↓␈↓↓ 245␈↓␈↓↓ 358␈↓␈↓↓ 381␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fat 73]␈↓ αxFateman,␈α!R.,␈α!`Reply␈α!to␈α!an␈α!Editorial',␈α!␈↓αSIGSAM␈α!Bulletin␈↓,␈α!No. 25,␈α p. 9-11,
␈↓ ↓H␈↓␈↓ βλMar. 1973. ␈↓↓[␈↓␈↓↓ 282␈↓␈↓↓ 366␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fel 68]␈↓ αxFeldman,␈αJ.,␈αand␈αGries,␈αD.,␈α`Translator␈αWriting␈αSystems',␈α␈↓αComm. ACM␈α11␈↓,␈α␈↓↓2␈↓,␈αp. 77-113,
␈↓ ↓H␈↓␈↓ βλFeb. 1968. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fen 69]␈↓ αxFenichel,␈α∪R.,␈α∪and␈α∀Yochelson,␈α∪J.,␈α∪`A␈α∀LISP␈α∪Garbage␈α∪Collector␈α∀for␈α∪Virtual-memory
␈↓ ↓H␈↓␈↓ βλComputer Systems', ␈↓αComm. ACM 12␈↓, ␈↓↓11␈↓, p. 611-612, Nov. 1969. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fin 76]␈↓ αxFinin,␈α∞T.,␈α∞and␈α
Rutter,␈α∞P.,␈α∞`Different␈α∞Fringe␈α
for␈α∞Different␈α∞Folk',␈α∞␈↓αSIGART␈α
Newsletter␈↓,
␈↓ ↓H␈↓␈↓ βλNo. 60, p. 4-5, Nov. 1976. ␈↓↓[␈↓␈↓↓ 209␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fis 70]␈↓ αxFisher,␈α∂D.,␈α∂`Control␈α∞Structures␈α∂for␈α∂Programming␈α∞Languages',␈α∂Ph.D. Thesis,␈α∂Dept.␈α∞of
␈↓ ↓H␈↓␈↓ βλComputer Science, Carnegie-Mellon University, 1970. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fis 72]␈↓ αxFischer,␈α∞M.,␈α∞`Lambda␈α∂Calculus␈α∞Schemata',␈α∞ACM␈α∂Conf.␈α∞on␈α∞Proving␈α∂assertions␈α∞about
␈↓ ↓H␈↓␈↓ βλprograms, ␈↓αSIGPLAN Notices␈↓, p. 104-109, Jan. 1972. ␈↓↓[␈↓␈↓↓ 192␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fri 74]␈↓ αxFriedman, D., ␈↓αThe Little LISPer␈↓, SRA, Menlo Park, 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fri 76a]␈↓ αxFriedman,␈α∞D.,␈α∞and␈α∞Wise,␈α∞D.,␈α∞`CONS␈α∞Should␈α∞Not␈α∞Evaluate␈α∞its␈α∞Arguments',␈α∂Proc.␈α∞3␈↓πrd␈↓
␈↓ ↓H␈↓␈↓ βλInt.␈α⊂Colloq.␈α⊂on␈α⊂Automata,␈α⊂Languages␈α⊂and␈α⊂Programming,␈α⊂Edinburgh␈α⊃Univ.␈α⊂Press,
␈↓ ↓H␈↓␈↓ βλp.257-284, July 1976. ␈↓↓[␈↓␈↓↓ 12␈↓␈↓↓ 207␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Fri 76b]␈↓ αxFriedman,␈α_D.,␈α_and␈α_Wise,␈α↔D.,␈α_`An␈α_Environment␈α_for␈α_Multiple-valued␈α↔Recursive
␈↓ ↓H␈↓␈↓ βλProcedures',␈α∃2␈↓πme␈↓␈α⊗Colloque␈α∃sur␈α∃la␈α⊗Programation,␈α∃Paris,␈α⊗Springer Verlag,␈α∃Berlin,
␈↓ ↓H␈↓␈↓ βλ1976. ␈↓↓[␈↓␈↓↓ 208␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gol 73]␈↓ αxGoldstein,␈α∂I.,␈α∂`Pretty␈α∂Printing: Converting␈α∂List␈α∂to␈α∂Linear␈α⊂Structure',␈α∂M.I.T. A.I. Lab,
␈↓ ↓H␈↓␈↓ βλMemo 279, Feb. 1973. ␈↓↓[␈↓␈↓↓ 389␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Goo 57]␈↓ αxGoodstein,␈α⊗R.,␈α↔␈↓αRecursive␈α⊗Number␈α⊗Theory␈↓,␈α↔North-Holland␈α⊗Pub.␈α↔Co.,␈α⊗Amsterdam,
␈↓ ↓H␈↓␈↓ βλ1957. ␈↓↓[␈↓␈↓↓ 1␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gor 73]␈↓ αxGordon,␈α∩M.,␈α⊃`Models␈α∩of␈α⊃Pure␈α∩LISP',␈α⊃Dept.␈α∩of␈α⊃Machine␈α∩Intelligence,␈α⊃Experimental
␈↓ ↓H␈↓␈↓ βλprogramming reports: No.30, University of Edinburgh, 1973. ␈↓↓[␈↓␈↓↓ 160␈↓␈↓↓ 162␈↓␈↓↓ 165␈↓␈↓↓ 221␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓10.␈↓
BIBLIOGRPAHY 405␈↓
␈↓ ↓H␈↓[Gor 75]␈↓ αxGordon,␈α∞M.,␈α∞`Towards␈α∞a␈α∞Semantic␈α
Theory␈α∞of␈α∞Dynamic␈α∞Binding',␈α∞Stanford␈α∞A.I.␈α
Lab.
␈↓ ↓H␈↓␈↓ βλMemo 265, Stanford University, 1975. ␈↓↓[␈↓␈↓↓ 160␈↓␈↓↓ 165␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Got 74]␈↓ αxGoto,␈αE.,␈α`Monocopy␈αand␈αAssociative␈αAlgorithms␈αin␈αan␈αExtended␈αLisp',␈αUniversity␈αof
␈↓ ↓H␈↓␈↓ βλTokyo, Japan, May 1974. ␈↓↓[␈↓␈↓↓ 44␈↓␈↓↓ 223␈↓␈↓↓ 267␈↓␈↓↓ 378␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Got 76]␈↓ αxGoto,␈α∂E.,␈α∞and␈α∂Kanada,␈α∂Y.,␈α∞`Recursive␈α∂Hashed␈α∂Data␈α∞Structures␈α∂with␈α∂Applications␈α∞to
␈↓ ↓H␈↓␈↓ βλPolynomial Manipulations', submitted to SYMSAC 76. ␈↓↓[␈↓␈↓↓ 73␈↓␈↓↓ 378␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gre 74]␈↓ αxGreenblatt,␈α)R.,␈α(`The␈α)LISP␈α(Machine',␈α)M.I.T.,␈α(Working␈α)paper␈α(No. 79,
␈↓ ↓H␈↓␈↓ βλNov. 1974. ␈↓↓[␈↓␈↓↓ 223␈↓␈↓↓ 280␈↓␈↓↓ 281␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gre 75]␈↓ αxGreussay,␈α(P.,␈α(`Manuel␈α(de␈α(Reference␈α(Provisoire: LISP T 1600',␈α'Universite
␈↓ ↓H␈↓␈↓ βλParis-Vincennes, Feb. 1975. ␈↓↓[␈↓␈↓↓ 205␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gre 76a]␈↓ αxGreussay,␈α
P.,␈α`Iterative␈α
Interpretation␈α
of␈αTail-Recursive␈α
LISP␈α
Procedures',␈αUniversity
␈↓ ↓H␈↓␈↓ βλof Vincennes, TR-20-76, Paris, Sep. 1976. ␈↓↓[␈↓␈↓↓ 216␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gre 76]␈↓ αxGreussay,␈α∪P.,␈α∪`An␈α∪Iterative␈α∪LISP␈α∪Solution␈α∪to␈α∪the␈α∪Samefringe␈α∪Problem',␈α∪␈↓αSIGART
␈↓ ↓H␈↓α␈↓ βλNewsletter␈↓, No. 59, p. 14, Aug. 1976. ␈↓↓[␈↓␈↓↓ 209␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gri 71]␈↓ αxGries,␈α≥D.,␈α≥␈↓αCompiler␈α≥Construction␈α≥for␈α≥Digital␈α≥Computers␈↓,␈α≥Wiley,␈α≡New␈α≥York,
␈↓ ↓H␈↓␈↓ βλ1971. ␈↓↓[␈↓␈↓↓ 258␈↓␈↓↓ 285␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gua 69]␈↓ αxGuard,␈α⊃J.,␈α⊂Bennet,␈α⊃J.,␈α⊂and␈α⊃Settle,␈α⊂L.,␈α⊃`Semi␈α⊂Automated␈α⊃Mathematics',␈α⊃␈↓αJACM 16␈↓,␈α⊂␈↓↓1␈↓,
␈↓ ↓H␈↓␈↓ βλp. 49-62, Jan. 1969. ␈↓↓[␈↓␈↓↓ 228␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Gun 76]␈↓ αxGunji,␈α∃T.,␈α∃`Analysis␈α∃of␈α∃Hash␈α∃Addressing␈α∃Methods',␈α∃Department␈α∃of␈α∃Information
␈↓ ↓H␈↓␈↓ βλSciences, TR 76-03, Univ. of Tokyo, Japan, Jan. 1976. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ham 69]␈↓ αxHammer,␈α⊗M.,␈α↔`Formal␈α⊗Definition␈α⊗of␈α↔BASEL',␈α⊗Mass.␈α⊗Computer␈α↔Associates,␈α⊗Inc.,
␈↓ ↓H␈↓␈↓ βλCA-6908-1511, Wakefield, Mass., 1969. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Han 69]␈↓ αxHansen,␈α∪W.,␈α∩`The␈α∪Impact␈α∩of␈α∪Storage␈α∩Management␈α∪on␈α∩Plex␈α∪Processing␈α∩Language
␈↓ ↓H␈↓␈↓ βλImplementation', Stanford Graphics Project, July 1969. ␈↓↓[␈↓␈↓↓ 358␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Han 71]␈↓ αxHansen,␈α
W.,␈α∞`Creation␈α
of␈α
Hierarchic␈α∞Text␈α
With␈α
a␈α∞Computer␈α
Display',␈α∞Ph.D.␈α
Thesis,
␈↓ ↓H␈↓␈↓ βλComputer Science Dept., Stanford Univ., June 1971. ␈↓↓[␈↓␈↓↓ 344␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Har 64]␈↓ αxHart,␈α⊂T.,␈α⊂and␈α⊂Evans,␈α⊂T.,␈α⊂`Notes␈α⊂on␈α⊂Implementing␈α⊂LISP␈α⊂for␈α⊂the␈α⊂M-460␈α⊂Computer',
␈↓ ↓H␈↓␈↓ βλp. 191-203 in [Ber 64]. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Har 75]␈↓ αxHoward,␈α
F.,␈α
`Documentation␈α
of␈αHarvard␈α
PDP-11␈α
LISP',␈α
unpublished␈αdocumentation,
␈↓ ↓H␈↓␈↓ βλ1975. ␈↓↓[␈↓␈↓↓ 226␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓406 BIBLIOGRAPHY␈↓ 710.␈↓
␈↓ ↓H␈↓[Hea 68]␈↓ αxHearn,␈α_A.,␈α_`REDUCE␈α_User's␈α→Manual',␈α_Stanford␈α_A.I. Lab␈α_Memo␈α→50,␈α_Stanford
␈↓ ↓H␈↓␈↓ βλUniversity, 1968. ␈↓↓[␈↓␈↓↓ 58␈↓␈↓↓ 396␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hen 75]␈↓ αxvon␈αHenke,␈αF.,␈α`On␈αthe␈αRepresentation␈αof␈αData␈αStructures␈αin␈αLCF␈αWith␈αApplications
␈↓ ↓H␈↓␈↓ βλto Program Generation', Stanford A.I. Lab. Memo 267, Sep. 1975. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hen 76]␈↓ αxHenderson,␈α∞P.,␈α∞and␈α
Morris,␈α∞J.,␈α∞`A␈α
Lazy␈α∞Evaluator',␈α∞SIGPLAN-SIGACT␈α
Symposium
␈↓ ↓H␈↓␈↓ βλon principles of programming languages, Altanta, p.95-103, Jan. 1976. ␈↓↓[␈↓␈↓↓ 207␈↓␈↓↓ 209␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hew 72]␈↓ αxHewitt,␈α∂C.,␈α∂`Description␈α∂and␈α∂Theoretical␈α∂Analysis␈α∂(using␈α∂Schemata)␈α∂of␈α∂PLANNER',
␈↓ ↓H␈↓␈↓ βλM.I.T. A.I. Lab., TR-258, April 1972. ␈↓↓[␈↓␈↓↓ 66␈↓␈↓↓ 215␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hew 74]␈↓ αxHewitt,␈α∞C.,␈α∂et.␈α∞al.,␈α∂`Behavioral␈α∞Semantics␈α∞of␈α∂Non-recursive␈α∞Control␈α∂Structures',␈α∞Proc.
␈↓ ↓H␈↓␈↓ βλColloque␈α∀sur␈α∪la␈α∀Programmation,␈α∪B. Robinet␈α∀ed.,␈α∪in␈α∀␈↓αLecture␈α∪Notes␈α∀in␈α∪Computer
␈↓ ↓H␈↓α␈↓ βλScience, No. 19␈↓, p. 385-407, Springer Verlag, Berlin, 1974. ␈↓↓[␈↓␈↓↓ 122␈↓␈↓↓ 209␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hew 75]␈↓ αxHewitt,␈α⊂C.,␈α⊂and␈α⊂Smith,␈α⊂B.,␈α∂`Towards␈α⊂a␈α⊂Programming␈α⊂Apprentice',␈α⊂␈↓αIEEE␈α⊂Trans.␈α∂on
␈↓ ↓H␈↓α␈↓ βλSoftware Engineering␈↓, SE-1, p. 26-45, Mar 1975. ␈↓↓[␈↓␈↓↓ 342␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hew 76]␈↓ αxHewitt,␈α≡C.,␈α≡`Viewing␈α≥Control␈α≡Structures␈α≡as␈α≥Patterns␈α≡of␈α≡Passing␈α≥Messages',
␈↓ ↓H␈↓␈↓ βλM.I.T. A.I. Lab, Working paper 92, April 1976. ␈↓↓[␈↓␈↓↓ 157␈↓␈↓↓ 215␈↓␈↓↓ 216␈↓␈↓↓ 339␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hoa 69]␈↓ αxHoare,␈αC.A.R.,␈α`An␈αAxiomatic␈αBasis␈αfor␈αComputer␈αProgramming',␈α␈↓αComm. ACM␈α12␈↓,␈α␈↓↓10␈↓,
␈↓ ↓H␈↓␈↓ βλp. 576-580, Oct. 1969. ␈↓↓[␈↓␈↓↓ 148␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hoa 73a]␈↓ αxHoare,␈α∞C.A.R.,␈α∞`Hints␈α∞on␈α∞Programming␈α∞Language␈α∞Design',␈α∞Stanford␈α∞A.I. Lab␈α∞Memo
␈↓ ↓H␈↓␈↓ βλ224, Dec. 1973. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hoa 73]␈↓ αxHoare,␈α C.A.R.,␈α `Recursive␈α Data␈α∨Structures',␈α Stanford␈α A.I. Lab␈α Memo␈α∨223,
␈↓ ↓H␈↓␈↓ βλOct. 1973. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Hop 69]␈↓ αxHopcroft␈α∪J.,␈α∩and␈α∪Ullman,␈α∪J.,␈α∩␈↓αFormal␈α∪Languages␈α∪and␈α∩their␈α∪Relation␈α∪to␈α∩Automata␈↓,
␈↓ ↓H␈↓␈↓ βλAddison-Wesley, Reading, Mass., 1969. ␈↓↓[␈↓␈↓↓ 24␈↓␈↓↓ 51␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Int 75]␈↓ αxTeitelman,␈α≥W.,␈α≥`INTERLISP␈α≥Reference␈α≥Manual',␈α≥Xerox␈α≥PARC,␈α≥Palo␈α≥Alto,
␈↓ ↓H␈↓␈↓ βλ1975. ␈↓↓[␈↓␈↓↓ 113␈↓␈↓↓ 180␈↓␈↓↓ 224␈↓␈↓↓ 254␈↓␈↓↓ 342␈↓␈↓↓ 344␈↓␈↓↓ 378␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ive 62]␈↓ αxIverson, K., ␈↓αA Programming Language␈↓, Wiley, New York, 1962. ␈↓↓[␈↓␈↓↓ 339␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Joh 71]␈↓ αxJohnston,␈α↔J.,␈α↔`The␈α↔Contour␈α↔Model␈α↔of␈α↔Block␈α↔Structured␈α↔Processes',␈α↔p. 55-82␈α↔in
␈↓ ↓H␈↓␈↓ βλ[DSIPL]. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Kan 75]␈↓ αxKanada,␈α⊗Y.,␈α∃`Implementation␈α⊗of␈α⊗HLISP␈α∃and␈α⊗Algebraic␈α⊗Manipulation␈α∃Language
␈↓ ↓H␈↓␈↓ βλREDUCE-2',␈α∩Information␈α⊃Sciences␈α∩Lab.,␈α⊃TR 75-01,␈α∩Univ.␈α⊃of␈α∩Tokyo,␈α∩Japan,␈α⊃Jan.
␈↓ ↓H␈↓␈↓ βλ1975. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓10.␈↓
BIBLIOGRPAHY 407␈↓
␈↓ ↓H␈↓[Kni 74]␈↓ αxKnight,␈α
T.,␈α
`The␈α
CONS␈αMicroprocessor',␈α
M.I.T.,␈α
Artificial␈α
Intelligence␈αWorking␈α
paper
␈↓ ↓H␈↓␈↓ βλNo. 80, . Cambrigde, Nov. 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Knu 68]␈↓ αxKnuth,␈α∩D.,␈α∩␈↓αThe␈α⊃Art␈α∩of␈α∩Computer␈α⊃Programming,␈α∩Non-numerical␈α∩Algorithms␈↓,␈α⊃Vol. 1,
␈↓ ↓H␈↓␈↓ βλAddison-Wesley, Reading, Mass., 1968. ␈↓↓[␈↓␈↓↓ 362␈↓␈↓↓ 369␈↓␈↓↓ 373␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Knu 72]␈↓ αxKnuth,␈α⊗D.,␈α⊗␈↓αThe␈α⊗Art␈α⊗of␈α∃Computer␈α⊗Programming,␈α⊗Searching␈α⊗and␈α⊗Sorting␈↓,␈α∃Vol. 3,
␈↓ ↓H␈↓␈↓ βλAddison-Wesley, Reading, Mass., 1972. ␈↓↓[␈↓␈↓↓ 258␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Knu 74]␈↓ αxKnuth,␈αD.,␈α`Structured␈αProgramming␈αWith␈αGO␈αTO␈αStatements',␈α␈↓αComputer␈αSurveys␈α6␈↓,
␈↓ ↓H␈↓␈↓ βλ4, p. 261-301, Dec. 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Lan 64]␈↓ αxLandin,␈α∀P.,␈α∪`The␈α∀Mechanical␈α∪Evaluation␈α∀of␈α∪Expressions',␈α∀␈↓αComputer Journal 6␈↓,␈α∪␈↓↓4␈↓,
␈↓ ↓H␈↓␈↓ βλp. 308-320, Apr. 1964. ␈↓↓[␈↓␈↓↓ 158␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Lan 66]␈↓ αxLandin,␈α⊂P.,␈α⊂`The␈α⊂Next␈α∂700␈α⊂Programming␈α⊂Languages',␈α⊂␈↓αComm. ACM 9␈↓,␈α⊂␈↓↓3␈↓,␈α∂p. 157-166,
␈↓ ↓H␈↓␈↓ βλMar. 1966. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[LCF 72]␈↓ αxMilner,␈α R.,␈α `Logic␈α for␈α Computable␈α Functions,␈α Description␈α of␈α!a␈α Machine
␈↓ ↓H␈↓␈↓ βλImplementation', Stanford A.I. Lab. Memo 169, 1972. ␈↓↓[␈↓␈↓↓ 87␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Leh 73]␈↓ αxLehmann,␈αD.,␈α`A␈αDirect␈αProof␈α
of␈αthe␈αChurch-Rosser␈αTheorem',␈αCenter␈α
for␈αComputer
␈↓ ↓H␈↓␈↓ βλand␈α∨Information␈α∨Sciences,␈α∨Technical␈α∨Report␈α∨No. 73-70,␈α∨Brown␈α∨University,
␈↓ ↓H␈↓␈↓ βλProvidence, R.I., August 1973. ␈↓↓[␈↓␈↓↓ 158␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Lev un]␈↓ αxLevin, M., `Course notes: 6.542', M.I.T., Cambridge, Mass., undated ␈↓↓[␈↓␈↓↓ 166␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Lin 73]␈↓ αxLindstrom,␈α∪G.,␈α∪`Algorithms␈α∪For␈α∪List␈α∪Structure␈α∪Condensation',␈α∪Dept.␈α∪of␈α∩Computer
␈↓ ↓H␈↓␈↓ βλScience, Technical Report 73-14, University of Pittsburgh, 1973. ␈↓↓[␈↓␈↓↓ 377␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Lis 74]␈↓ αxLiskov,␈α⊃B.,␈α⊃and␈α⊃Zilles,␈α⊃S.,␈α⊃`Programming␈α⊃With␈α⊃Abstract␈α⊃Data␈α⊃Structures',␈α∩Proc.␈α⊃of
␈↓ ↓H␈↓␈↓ βλSymposium on Very high level languages, ␈↓αSIGPLAN Notices␈↓, Apr. 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Lon 71]␈↓ αxLondon,␈α∂R.,␈α∂`Correctness␈α∂of␈α∂Two␈α∂Compilers␈α∂for␈α∂a␈α∂LISP␈α∂Subset',␈α⊂Stanford␈α∂A.I. Lab.
␈↓ ↓H␈↓␈↓ βλMemo 151, Oct., 1971. ␈↓↓[␈↓␈↓↓ 318␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Lug 73]␈↓ αxLugger,␈α∨J.,␈α∨and␈α∨Melenk,␈α∨H.,␈α∨`Darstellung␈α∨und␈α Bearbeitung␈α∨Umfangreicher
␈↓ ↓H␈↓␈↓ βλLISP-programme', ␈↓αAngewandte Informatik␈↓, p. 257-263, June 1973. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[MAC 74]␈↓ αxBogen,␈α∞R.,␈α∞`MACSYMA␈α∞Reference␈α∞Manual',␈α∞Project␈α∞MAC,␈α∞Mathlab␈α∞Group,␈α
M.I.T.,
␈↓ ↓H␈↓␈↓ βλCambridge, 1974. ␈↓↓[␈↓␈↓↓ 58␈↓␈↓↓ 366␈↓␈↓↓ 396␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Man 74]␈↓ αxManna,␈α Z.,␈α ␈↓αMathematical␈α Theory␈α of␈α Computation␈↓,␈α!McGraw-Hill,␈α New York,
␈↓ ↓H␈↓␈↓ βλ1974. ␈↓↓[␈↓␈↓↓ 145␈↓␈↓↓ 218␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓408 BIBLIOGRAPHY␈↓ 710.␈↓
␈↓ ↓H␈↓[McB 63]␈↓ αxMcBeth,␈α∂H.␈α∂ `On␈α∂the␈α∂Reference␈α∞Counter␈α∂Method',␈α∂(letter),␈α∂␈↓αComm.␈α∂ACM 6␈↓,␈α∂␈↓↓9␈↓,␈α∞p. 575,
␈↓ ↓H␈↓␈↓ βλSep 1963. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[McC 60a]␈↓ αxMcCarthy,␈α⊗J,␈α∃et.␈α⊗al.,␈α∃`LISP␈α⊗1␈α∃Programmer's␈α⊗Manual',␈α∃Computation␈α⊗Center␈α∃and
␈↓ ↓H␈↓␈↓ βλResearch Laboratory of Electronics, M.I.T., Cambridge, 1960. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[McC 60]␈↓ αxMcCarthy,␈αJ.,␈α
`Recursive␈αFunctions␈α
of␈αSymbolic␈α
Expressions␈αand␈α
Their␈αComputation
␈↓ ↓H␈↓␈↓ βλby Machine', ␈↓αComm. ACM␈↓, p. 184-195, April 1960. ␈↓↓[␈↓␈↓↓ 98␈↓␈↓↓ 171␈↓␈↓↓ 217␈↓␈↓↓ 267␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[McC 62]␈↓ αxMcCarthy,␈α
J.,␈α
`Towards␈α
a␈αMathematical␈α
Science␈α
of␈α
Computation',␈α
IFIPS␈αProceedings
␈↓ ↓H␈↓␈↓ βλof Munich Conference 1962, North Holland, Amsterdam, 1963. ␈↓↓[␈↓␈↓↓ 150␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[McC 63]␈↓ αxMcCarthy,␈α∀J.,␈α∀␈↓αA␈α∀Basis␈α∀for␈α∀a␈α∀Mathematical␈α∀Theory␈α∀of␈α∀Computation,␈α∀in␈α∀Computer
␈↓ ↓H␈↓α␈↓ βλProgramming and Formal Systems␈↓, North Holland, Amsterdam, 1963. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[McC 65]␈↓ αxMcCarthy,␈α∪J,␈α∀et.␈α∪al.,␈α∀`LISP␈α∪1.5␈α∪Programmer's␈α∀Manual',␈α∪M.I.T.␈α∀Press,␈α∪Cambridge,
␈↓ ↓H␈↓␈↓ βλ1965. ␈↓↓[␈↓␈↓↓ 105␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[McC 66]␈↓ αxMcCarthy,␈α∞J.,␈α∞`A␈α∞Formal␈α
Description␈α∞of␈α∞a␈α∞Subset␈α
of␈α∞ALGOL',␈α∞in␈α∞␈↓αFormal␈α
Language
␈↓ ↓H␈↓α␈↓ βλDescription␈α∃Languages␈α∃for␈α∃Computer␈α∃Programming␈↓,␈α∃North Holland,␈α∃Amsterdam,
␈↓ ↓H␈↓␈↓ βλ1966. ␈↓↓[␈↓␈↓↓ 149␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[McC 76]␈↓ αxMcCarthy,␈α⊂J.,␈α⊂␈↓αRecursive␈α⊂Programming␈α⊃in␈α⊂LISP␈↓,␈α⊂CS206␈α⊂notes,␈α⊃Stanford␈α⊂University,
␈↓ ↓H␈↓␈↓ βλ1976. ␈↓↓[␈↓␈↓↓ 318␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[McD 75]␈↓ αxMcDermott,␈αD.,␈α
`Very␈αLarge␈αPLANNER-type␈α
Data␈αBases',␈αM.I.T. A.I. Lab␈α
Memo 339,
␈↓ ↓H␈↓␈↓ βλCambridge, Mass., Sep. 1975. ␈↓↓[␈↓␈↓↓ 68␈↓␈↓↓ 237␈↓␈↓↓ 238␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Men 64]␈↓ αxMendelson,␈α~E.,␈α→␈↓αIntroduction␈α~to␈α~Mathematical␈α→Logic␈↓,␈α~Van␈α~Nostrand,␈α→Princeton,
␈↓ ↓H␈↓␈↓ βλNew Jersey, 1964. ␈↓↓[␈↓␈↓↓ 95␈↓␈↓↓ 147␈↓␈↓↓ 148␈↓␈↓↓ 159␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mic 71]␈↓ αxSussman,␈α≤G.,␈α≤et␈α≤al.,␈α≤`Micro-PLANNER␈α≤Reference␈α≤Manual',␈α≤M.I.T.,␈α≠A.I. Lab.
␈↓ ↓H␈↓␈↓ βλMemo 203a, Cambridge, Mass., Dec 1971. ␈↓↓[␈↓␈↓↓ 384␈↓␈↓↓ 386␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mil 73]␈↓ αxMilner,␈αR.,␈α`λ-Calculus␈αand␈αthe␈α
Semantics␈αof␈αProgramming␈αLanguages',␈αLecture␈α
Notes,
␈↓ ↓H␈↓␈↓ βλComputer Science Dept., University of Edinburgh, 1973-74. ␈↓↓[␈↓␈↓↓ 158␈↓␈↓↓ 166␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Min 70]␈↓ αxMinsky,␈α∂M.,␈α∂`Form␈α∞and␈α∂Content␈α∂in␈α∂Computer␈α∞Science:␈α∂1970␈α∂ACM␈α∂Turing␈α∞Lecture',
␈↓ ↓H␈↓␈↓ βλ␈↓αJACM 17␈↓, ␈↓↓2␈↓, p. 197-215, Apr. 1970. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mit 70]␈↓ αxMitchell,␈α→J.,␈α→`The␈α→Design␈α→&␈α→Construction␈α→of␈α→Flexible␈α→&␈α→Efficient␈α→Interactive
␈↓ ↓H␈↓␈↓ βλProgramming␈α.Systems',␈α/Ph.D. Thesis,␈α.Carnegie-Mellon␈α/Unversity,␈α.June
␈↓ ↓H␈↓␈↓ βλ1970. ␈↓↓[␈↓␈↓↓ 138␈↓␈↓↓ 311␈↓␈↓↓ 380␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mli 73]␈↓ αxSmith,␈α∂D.,␈α⊂and␈α∂Enea,␈α⊂H.,␈α∂`MLISP2',␈α⊂Stanford␈α∂A.I. Lab␈α⊂Memo␈α∂195,␈α⊂Stanford␈α∂Univ.,
␈↓ ↓H␈↓␈↓ βλ1973. ␈↓↓[␈↓␈↓↓ 384␈↓␈↓↓ 396␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓10.␈↓
BIBLIOGRPAHY 409␈↓
␈↓ ↓H␈↓[Mon 73]␈↓ αxMontangero,␈α⊃C.,␈α⊃et␈α⊃al.,␈α⊃`An␈α⊂Extended␈α⊃LISP␈α⊃System␈α⊃for␈α⊃Complex␈α⊂Control-structure
␈↓ ↓H␈↓␈↓ βλProgramming', University of Pisa, 1973. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mon 75a]␈↓ αxMontangero,␈α~C.,␈α≠et␈α~al.,␈α~`MAGMA-Lisp:␈α≠A␈α~`Machine␈α~Language'␈α≠for␈α~Artifical
␈↓ ↓H␈↓␈↓ βλIntelligence', Proc. 4␈↓πth␈↓ Int. J. Conf. on A.I., Tbilisi, p. 556-561, Sep. 1975. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mon 75]␈↓ αxMontangero,␈α
C.␈α
et␈α
al.,␈α
`Information␈α
Management␈α
in␈α
Context␈α
Trees',␈α
University␈αof␈α
Pisa,
␈↓ ↓H␈↓␈↓ βλN.I. B75-21, Oct. 1975. ␈↓↓[␈↓␈↓↓ 280␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Moo 74]␈↓ αxMoon,␈α∂D.,␈α⊂`MacLISP␈α∂Reference␈α∂Manual',␈α⊂Laboratory␈α∂for␈α∂Computer␈α⊂Science,␈α∂M.I.T.,
␈↓ ↓H␈↓␈↓ βλCambridge, Mass, 1974. ␈↓↓[␈↓␈↓↓ 113␈↓␈↓↓ 134␈↓␈↓↓ 180␈↓␈↓↓ 181␈↓␈↓↓ 184␈↓␈↓↓ 260␈↓␈↓↓ 344␈↓␈↓↓ 366␈↓␈↓↓ 378␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Moor 74]␈↓ αxMoore,␈αJ,␈α
`Introducing␈αPROG␈α
to␈αthe␈α
Pure␈αLISP␈α
Theorem␈αProver',␈α
CSL 74-3,␈αXerox
␈↓ ↓H␈↓␈↓ βλPARC, Palo Alto, Dec 1974. ␈↓↓[␈↓␈↓↓ 44␈↓␈↓↓ 171␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Moor 75a]␈↓ αxMoore,␈α
J,␈α
`The␈αINTERLISP␈α
Virtual␈α
Machine␈αSpecification',␈α
(in␈α
preparation),␈αXerox
␈↓ ↓H␈↓␈↓ βλPARC, Palo Alto, 1975. ␈↓↓[␈↓␈↓↓ 149␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Moor 75b]␈↓ αxMoore,␈αJ,␈α`Computational␈αLogic:␈α
Structure␈αSharing␈αand␈αProof␈αof␈α
Program␈αProperties
␈↓ ↓H␈↓␈↓ βλPart II', CSL 75-2, Xerox PARC, Palo Alto, Apr 1975. ␈↓↓[␈↓␈↓↓ 87␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mor 55]␈↓ αxMorris,␈α∀C.,␈α∃`Foundations␈α∀of␈α∃the␈α∀Theory␈α∀of␈α∃Signs',␈α∀␈↓αInternational␈α∃Encyclopedia␈α∀of
␈↓ ↓H␈↓α␈↓ βλUnified Science␈↓, Vol 1, No 2, University of Chicago press, 1955. ␈↓↓[␈↓␈↓↓ 147␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mor 68]␈↓ αxMorris,␈α∀J.,␈α∪`Lambda-calculus␈α∀Models␈α∀of␈α∪Programming␈α∀Languages',␈α∀Project␈α∪MAC,
␈↓ ↓H␈↓␈↓ βλM.I.T., MAC-TR57, Dec 1968. ␈↓↓[␈↓␈↓↓ 21␈↓␈↓↓ 166␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mor 73]␈↓ αxMorris,␈α⊃L.,␈α∩`Advice␈α⊃on␈α∩Structuring␈α⊃Compilers␈α⊃and␈α∩Proving␈α⊃Them␈α∩Correct',␈α⊃ACM
␈↓ ↓H␈↓␈↓ βλSymposium␈α∨on␈α∨Principles␈α≡of␈α∨Programming␈α∨Languages,␈α∨Boston,␈α≡p. 144-152,
␈↓ ↓H␈↓␈↓ βλ1973. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mor 74]␈↓ αxMorris,␈α≥J.,␈α≥`Towards␈α≤More␈α≥Flexible␈α≥Type␈α≤Systems',␈α≥Proc.␈α≥Colloque␈α≥sur␈α≤la
␈↓ ↓H␈↓␈↓ βλProgrammation, Paris, April 1974, p. 377-383, Springer Verlag, Berlin, 1974. ␈↓↓[␈↓␈↓↓ 35␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mos 70]␈↓ αxMoses,␈α
J.,␈α
`The␈α
Function␈α
of␈αFUNCTION␈α
in␈α
LISP',␈α
␈↓αSIGSAM␈α
Bulletin␈↓,␈α
p. 13-27,␈αJuly
␈↓ ↓H␈↓␈↓ βλ1970. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mos 74]␈↓ αxMoses,␈α∀J.,␈α∀`MACSYMA - ␈α∃The␈α∀Fifth␈α∀Year',␈α∃␈↓αSIGSAM␈α∀Bulletin␈↓,␈α∀␈↓↓8␈↓,␈α∃␈↓α3␈↓,␈α∀p. 105-110,
␈↓ ↓H␈↓␈↓ βλAug 1974. ␈↓↓[␈↓␈↓↓ 58␈↓␈↓↓ 366␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mot 76]␈↓ αxMotoyoshi,␈α
F.,␈α`A␈α
Portable␈αLISP␈α
Compiler␈α
on␈αa␈α
Hypothetical␈αLISP␈α
Machine',␈αDept.␈α
of
␈↓ ↓H␈↓␈↓ βλInfo. Science, TR 76-5, University of Tokyo, Japan, Jan. 1976. ␈↓↓[␈↓␈↓↓ 229␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Mud 75]␈↓ αxGalley,␈α∃S.W.,␈α⊗and␈α∃Pfister,␈α∃G.,␈α⊗`The␈α∃MDL␈α∃Language',␈α⊗Programming␈α∃Technology
␈↓ ↓H␈↓␈↓ βλDivision␈α6Doc. SYS.11.01,␈α6Project␈α6Mac,␈α6M.I.T.,␈α7Cambridge,␈α6Mass.,
␈↓ ↓H␈↓␈↓ βλNov. 1975. ␈↓↓[␈↓␈↓↓ 281␈↓␈↓↓ 386␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓410 BIBLIOGRAPHY␈↓ 710.␈↓
␈↓ ↓H␈↓[Mul 76]␈↓ αxMuller,␈α∩K.,␈α∩`On␈α∪the␈α∩Feasibility␈α∩of␈α∪Concurrent␈α∩Garbage␈α∩Collection',␈α∪Ph.D.␈α∩Thesis,
␈↓ ↓H␈↓␈↓ βλUniversity of Delft, 1976. ␈↓↓[␈↓␈↓↓ 267␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[New 61]␈↓ αxNewell,␈α⊂A.,␈α⊂␈↓αInformation␈α⊂Processing␈α⊂Language␈α⊂V␈α⊂Manual␈↓,␈α⊂Prentice␈α⊂Hall,␈α∂Englewood
␈↓ ↓H␈↓␈↓ βλCliffs, New Jersey, 1961. ␈↓↓[␈↓␈↓↓ 214␈↓␈↓↓ 222␈↓␈↓↓ 227␈↓␈↓↓ 237␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[New 75]␈↓ αxNewey,␈α∂M.,␈α⊂`Formal␈α∂Semantics␈α⊂of␈α∂LISP␈α∂with␈α⊂Applications␈α∂to␈α⊂Program␈α∂Correctness',
␈↓ ↓H␈↓␈↓ βλStanford A.I. Lab Memo 257, Stanford Univ., Jan 1975. ␈↓↓[␈↓␈↓↓ 87␈↓␈↓↓ 318␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Nor 70]␈↓ αxNordstrom,␈α
M.,␈α
et␈α
al.,␈α
`LISP␈α
F1␈α
-␈α
A␈α
Fortran␈α
Implementation␈α
of␈α
LISP␈α
1.5',␈αComputer
␈↓ ↓H␈↓␈↓ βλScience Dept, Uppsala University, Sweden, 1970. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Nor 76]␈↓ αxNorman,␈α∪E.,␈α∀`Documentation␈α∪for␈α∪1100␈α∀LISP␈α∪Implementation',␈α∀unpublished␈α∪paper,
␈↓ ↓H␈↓␈↓ βλUniversity of Wisconsin-Madison, 1976. ␈↓↓[␈↓␈↓↓ 246␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Org 71]␈↓ αxOrganick,␈α∪E.,␈α∪and␈α∪Cleary,␈α∪J.,␈α∪`A␈α∩Data␈α∪Structure␈α∪Model␈α∪of␈α∪the␈α∪B6700␈α∩Computer
␈↓ ↓H␈↓␈↓ βλSystem', p. 83-145 in [DSIPL]. ␈↓↓[␈↓␈↓↓ 349␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Org 73]␈↓ αxOrganick,␈α≤E.,␈α≤␈↓αComputer␈α≥System␈α≤Organization:␈α≤the␈α≤B5700/6700␈α≥Series␈↓,␈α≤ACM
␈↓ ↓H␈↓␈↓ βλMonograph Series, Academic Press, New York, 1973. ␈↓↓[␈↓␈↓↓ 222␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Pac 73]␈↓ αxPacini,␈α↔G.,␈α⊗`An␈α↔Optimal␈α↔Fix-point␈α⊗Computation␈α↔Rule␈α⊗for␈α↔a␈α↔Simple␈α⊗Recursive
␈↓ ↓H␈↓␈↓ βλLanguage', University of Pisa, N.I. B75-10, Oct. 1973. ␈↓↓[␈↓␈↓↓ 207␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Pag 76]␈↓ αxPage, R., LISP for Fairchild F8, Private communication, 1976. ␈↓↓[␈↓␈↓↓ 226␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Per 67]␈↓ αxPerlis,␈α∃A.,␈α∀`The␈α∃Synthesis␈α∀of␈α∃Algorithmic␈α∀Systems:␈α∃1966␈α∀ACM␈α∃Turing␈α∀Lecture',
␈↓ ↓H␈↓␈↓ βλ␈↓αJACM 14␈↓, ␈↓↓1␈↓, p. 1-9, Jan. 1967. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Plo 74]␈↓ αxPlotkin,␈α⊃G.,␈α⊃`Call-by-name,␈α⊃Call-by-value␈α⊂and␈α⊃the␈α⊃λ-Calculus',␈α⊃␈↓αTheoretical␈α⊂Computer
␈↓ ↓H␈↓α␈↓ βλScience 1␈↓, p. 125-159, 1975. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Pop 68a]␈↓ αxPopplestone,␈α∀R.,␈α∀`The␈α∀Design␈α∀Philosophy␈α∀of␈α∀POP-2',␈α∀in␈α∀␈↓αMachine␈α∀Intelligence␈α∀3␈↓,
␈↓ ↓H␈↓␈↓ βλAmerican Elsevier, New York, 1968. ␈↓↓[␈↓␈↓↓ 145␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Pop 68]␈↓ αxBurstall, R., et al., ␈↓αPOP2 Papers␈↓, Oliver & Boyd, Edinburgh, 1968. ␈↓↓[␈↓␈↓↓ 146␈↓␈↓↓ 358␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Pra 73]␈↓ αxPratt,␈α
V.,␈α`Top-down␈α
Operator␈αPrecedence',␈α
Proceedings␈αof␈α
the␈αACM␈α
Symposium␈αon
␈↓ ↓H␈↓␈↓ βλPrinciples of Programming, p. 41-51, 1973. ␈↓↓[␈↓␈↓↓ 148␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Pra 76]␈↓ αxPratt,␈α∞V.,␈α∞`CGOL - An␈α∞Alternative␈α∞External␈α∞Representation␈α∞for␈α∞LISP␈α∞Users',␈α∞M.I.T.
␈↓ ↓H␈↓␈↓ βλA.I. Lab, Working Paper No. 89, 1976. ␈↓↓[␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Pre 72]␈↓ αxPrenner,␈α∃C.,␈α∀`Multi-path␈α∃Control␈α∃Structures␈α∀for␈α∃Programming␈α∃Languages',␈α∀Ph.D.
␈↓ ↓H␈↓␈↓ βλThesis, Center for Research in Computing Technology, Harvard Univ., 1972. ␈↓↓[␈↓␈↓↓ 215␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓10.␈↓
BIBLIOGRPAHY 411␈↓
␈↓ ↓H␈↓[Pre 76a]␈↓ αxPrenner,␈α∂C.,␈α∂`Data␈α⊂structures␈α∂for␈α∂Spaghetti␈α⊂LISP',␈α∂unpublished␈α∂notes,␈α⊂University␈α∂of
␈↓ ↓H␈↓␈↓ βλCalifornia, Berkeley, Calif, 1976. ␈↓↓[␈↓␈↓↓ 215␈↓␈↓↓ 246␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Pre 76b]␈↓ αxPrenner,␈α⊃C.,␈α⊃`Implementation␈α⊂for␈α⊃Spaghetti␈α⊃EL1',␈α⊂unpublished␈α⊃notes,␈α⊃University␈α⊂of
␈↓ ↓H␈↓␈↓ βλCalifornia, Berkeley, Calif, 1976. ␈↓↓[␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[QA4 72]␈↓ αxRulifson,␈α∂J.,␈α∂et. al.,␈α∂`QA4: A␈α∂Procedural␈α∂Calculus␈α∂for␈α∂Intuitive␈α⊂Reasoning',␈α∂Stanford
␈↓ ↓H␈↓␈↓ βλResearch Institute, TN-73, Menlo Park, Cal., Nov. 1972. ␈↓↓[␈↓␈↓↓ 68␈↓␈↓↓ 384␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Qua 68]␈↓ αxQuam, L., `SDIO Manual', unpublished paper, Stanford, 1968. ␈↓↓[␈↓␈↓↓ 396␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Qua 72]␈↓ αxQuam,␈αL.,␈αand␈αDiffie,␈αW.,␈α`Stanford␈αLISP 1.6␈αManual',␈αStanford␈αA.I. Lab.,␈αOperating
␈↓ ↓H␈↓␈↓ βλNote 28.7, Stanford Univ., 1972. ␈↓↓[␈↓␈↓↓ 113␈↓␈↓↓ 180␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Rey 72]␈↓ αxReynolds,␈α∃J.,␈α⊗`Definitional␈α∃Interpreters␈α⊗for␈α∃High-order␈α⊗Programming␈α∃Languages',
␈↓ ↓H␈↓␈↓ βλProceedings␈α!of␈α!the␈α!ACM␈α!National␈α!convention,␈α!1972,␈α"p. 717-740,␈α!ACM,
␈↓ ↓H␈↓␈↓ βλ1972. ␈↓↓[␈↓␈↓↓ 122␈↓␈↓↓ 192␈↓␈↓↓ 205␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ric 74]␈↓ αxRich,␈α∞C.,␈α
and␈α∞Shrobe,␈α
H.,␈α∞`Understanding␈α
LISP␈α∞Programs: Towards␈α∞a␈α
Programming
␈↓ ↓H␈↓␈↓ βλApprentice', M.I.T. A.I. Lab, Working paper 82, Dec. 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ris 73]␈↓ αxRisch,␈α∀T.,␈α∀`REMREC - A␈α∀Program␈α∀for␈α∀Automatic␈α∀Recursion␈α∀Removal␈α∃in␈α∀LISP',
␈↓ ↓H␈↓␈↓ βλDatalogilaboratoriet, DLU 73/24, Uppsala Univ., Nov. 1973. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Riv 76]␈↓ αxRivest,␈α∪R.,␈α∪`On␈α∪Self-organizing␈α∪Sequential␈α∪Search␈α∪Heuristics',␈α∪␈↓αComm.␈α∪ACM␈α∪19␈↓,␈α∪␈↓↓2␈↓,
␈↓ ↓H␈↓␈↓ βλp. 63-67, Feb. 1976. ␈↓↓[␈↓␈↓↓ 242␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Rob 65]␈↓ αxRobinson,␈αJ.,␈α`A␈αMachine-oriented␈αLogic␈αBased␈αon␈αthe␈αResolution␈αPrinciple',␈α␈↓αJournal
␈↓ ↓H␈↓α␈↓ βλACM 12␈↓, ␈↓↓1␈↓, p. 23-41, Jan 1965. ␈↓↓[␈↓␈↓↓ 68␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Roc 71]␈↓ αxRochfeld,␈αA.,␈α`New␈αLISP␈αTechniques␈αfor␈αa␈αPaging␈αEnvironment',␈α␈↓αComm.␈αACM␈α14␈↓,␈α␈↓↓12␈↓,
␈↓ ↓H␈↓␈↓ βλp. 791-795, Dec 1971. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Rog 67]␈↓ αxRogers,␈α∂H.,␈α∂␈↓αTheory␈α∂of␈α∞Recursive␈α∂Functions␈α∂&␈α∂Effective␈α∂Computability␈↓,␈α∞McGraw-Hill,
␈↓ ↓H␈↓␈↓ βλNew York, 1967. ␈↓↓[␈↓␈↓↓ 21␈↓␈↓↓ 145␈↓␈↓↓ 216␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sam 75]␈↓ αxSamet,␈α~H.,␈α~`Automatically␈α~Proving␈α~the␈α~Correctness␈α~of␈α≠Translations␈α~Involving
␈↓ ↓H␈↓␈↓ βλOptimized Code', Stanford A.I. Lab. Memo 259, May 1975. ␈↓↓[␈↓␈↓↓ 171␈↓␈↓↓ 242␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[San 75a]␈↓ αxSandewall,␈α∩E.,␈α∩`Ideas␈α∩About␈α∩Management␈α∩of␈α∩LISP␈α∩Data␈α∩Bases',␈α∩M.I.T.␈α∩A.I.␈α∩Lab.,
␈↓ ↓H␈↓␈↓ βλMemo 332, May 1975. ␈↓↓[␈↓␈↓↓ 245␈↓␈↓↓ 246␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[San 75]␈↓ αxSandewall,␈α∂E.,␈α∞`Some␈α∂Observations␈α∞on␈α∂Conceptual␈α∞Programming',␈α∂Computer␈α∞Science
␈↓ ↓H␈↓␈↓ βλDept., Uppsala University, Sweden, 1975. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓412 BIBLIOGRAPHY␈↓ 710.␈↓
␈↓ ↓H␈↓[San 76]␈↓ αxSandewall,␈α
E.,␈α∞`Programming␈α
in␈α
an␈α∞Interactive␈α
Environment:␈α
The␈α∞LISP␈α
Experience',
␈↓ ↓H␈↓␈↓ βλLinkoping University, Sweden, 1976. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sau 64]␈↓ αxSaunders,␈α∨R.,␈α≡`The␈α∨LISP␈α≡System␈α∨for␈α≡the␈α∨Q-32␈α≡Computer',␈α∨p. 220-231␈α≡in
␈↓ ↓H␈↓␈↓ βλ[Ber 64]. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sch 67]␈↓ αxSchorr,␈α↔H.,␈α↔and␈α↔Waite,␈α_W.,␈α↔`An␈α↔Efficient␈α↔Machine-independent␈α_Procedure␈α↔for
␈↓ ↓H␈↓␈↓ βλGarbage␈α↔Collection␈α⊗in␈α↔Various␈α↔List␈α⊗Structures',␈α↔␈↓αComm. ACM 10␈↓,␈α↔␈↓↓8␈↓,␈α⊗p. 501-506,
␈↓ ↓H␈↓␈↓ βλAug. 1967. ␈↓↓[␈↓␈↓↓ 373␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sco 70]␈↓ αxScott,␈α⊂D.,␈α⊂`Outline␈α⊂of␈α⊂a␈α⊂Mathematical␈α⊂Theory␈α⊂of␈α⊂Computation',␈α⊃Oxford␈α⊂University
␈↓ ↓H␈↓␈↓ βλComputing Labs, PRG-2, Oxford University, 1970. ␈↓↓[␈↓␈↓↓ 160␈↓␈↓↓ 161␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sco 72]␈↓ αxScott,␈α⊂D.,␈α⊃`Mathematical␈α⊂Concepts␈α⊂in␈α⊃Programming␈α⊂Languages',␈α⊃AFIPS␈α⊂Conference
␈↓ ↓H␈↓␈↓ βλProceedings, Vol 40, p. 225-234, 1972. ␈↓↓[␈↓␈↓↓ 147␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sco 73]␈↓ αxScott,␈αD.,␈α`Models␈αfor␈αvarious␈αtype-free␈αcalculi',␈αin␈α␈↓αLogic,␈αMethodology,␈α
and␈αPhilosophy
␈↓ ↓H␈↓α␈↓ βλof Science IV␈↓, North Holland, p. 157-187, 1973. ␈↓↓[␈↓␈↓↓ 160␈↓␈↓↓ 161␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sik 76]␈↓ αxSiklossy,␈α→L.,␈α→␈↓αLet's␈α~Talk␈α→LISP␈↓,␈α→Prentice␈α~Hall,␈α→Englewood␈α→Cliffs,␈α~New␈α→Jersey,
␈↓ ↓H␈↓␈↓ βλ1976. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sta 74]␈↓ αxvon␈α~Staa,␈α≠A.,␈α~`Data␈α~Transmission␈α≠and␈α~Modularity␈α~Aspects␈α≠of␈α~Programming
␈↓ ↓H␈↓␈↓ βλLanguages',␈α⊂Dept.␈α⊂of␈α⊂Computer␈α⊂Science,␈α⊂Research␈α⊂Report␈α⊂CS-74-17,␈α⊂University␈α⊂of
␈↓ ↓H␈↓␈↓ βλWaterloo, Ontario, October 1974. ␈↓↓[␈↓␈↓↓ 146␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ste 73]␈↓ αxSteele, G., `BIBOP LISP Memo', unpublished MIT paper, 1973. ␈↓↓[␈↓␈↓↓ 246␈↓␈↓↓ 377␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ste 76a]␈↓ αxSteele,␈α∪G.,␈α∪`Multiprocessing␈α∩Compactifying␈α∪Garbage␈α∪Collection',␈α∪␈↓αComm. ACM 18␈↓,␈α∩␈↓↓9␈↓,
␈↓ ↓H␈↓␈↓ βλp. 495-508, Sep. 1967. ␈↓↓[␈↓␈↓↓ 377␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ste 76b]␈↓ αxSteele,␈α.G.,␈α.and␈α.Sussman,␈α.G.,␈α.`LAMBDA: The␈α.Ultimate␈α.Imperative',
␈↓ ↓H␈↓␈↓ βλM.I.T. A.I. Memo 353, Mar. 1976. ␈↓↓[␈↓␈↓↓ 136␈↓␈↓↓ 157␈↓␈↓↓ 205␈↓␈↓↓ 339␈↓␈↓↓ 385␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ste 76c]␈↓ αxSteele,␈α.G.,␈α.`LAMBDA: The␈α.Ultimate␈α.Declarative',␈α-M.I.T. A.I. Memo 379,
␈↓ ↓H␈↓␈↓ βλOct. 1976. ␈↓↓[␈↓␈↓↓ 157␈↓␈↓↓ 385␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ste pc]␈↓ αxSteele, G., private communications. ␈↓↓[␈↓␈↓↓ 39␈↓␈↓↓ 141␈↓␈↓↓ 345␈↓␈↓↓ 358␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Stei 74]␈↓ αxSteiger, R., `Actor Machine Architecture', M.S. Thesis, M.I.T., 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sto 75]␈↓ αxStoyan,␈α⊂H.,␈α∂`Comparison␈α⊂of␈α∂Two␈α⊂LISP␈α∂Compilers: Stanford␈α⊂Versus␈α∂DOS/ES-LISP',
␈↓ ↓H␈↓␈↓ βλ␈↓αElektronische Informationsverarbeitung und Kybernetik 11␈↓, p. 371-375, 1975. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Str 67]␈↓ αxStrachey,␈α!C.,␈α `Fundamental␈α!Concepts␈α in␈α!Programming␈α!Languages',␈α NATO
␈↓ ↓H␈↓␈↓ βλConference, Copenhagen, 1967. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓10.␈↓
BIBLIOGRPAHY 413␈↓
␈↓ ↓H␈↓[Str 73]␈↓ αxStrachey,␈α∂C.,␈α∞`Varieties␈α∂of␈α∂Programming␈α∞Languages',␈α∂Oxford␈α∂University␈α∞Computing
␈↓ ↓H␈↓␈↓ βλLabs, PRG-10, Oxford University, 1973. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Str 74a]␈↓ αxStrachey,␈α∪C.,␈α∀and␈α∪Wadsworth,␈α∪C.,␈α∀`Continuations:␈α∪A␈α∪Mathematical␈α∀Semantics␈α∪for
␈↓ ↓H␈↓␈↓ βλHandling␈α~Full␈α→Jumps',␈α~Oxford␈α→University␈α~Computing␈α~Laboratory,␈α→Technical
␈↓ ↓H␈↓␈↓ βλMonograph PRG-11, Jan 1974. ␈↓↓[␈↓␈↓↓ 192␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Str 74]␈↓ αxFoy,␈α⊗N.,␈α⊗`The␈α⊗Words␈α⊗Games␈α⊗of␈α⊗the␈α⊗Night␈α⊗Bird:␈α⊗Interview␈α⊗with␈α⊗C.␈α∃Strachey',
␈↓ ↓H␈↓␈↓ βλ␈↓αComputing Europe␈↓, p. 10-11, Aug 15, 1974. ␈↓↓[␈↓␈↓↓ 88␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sus 75]␈↓ αxSussman,␈α⊗G.,␈α⊗and␈α⊗Steele,␈α⊗G.,␈α⊗`SCHEME:␈α⊗an␈α⊗Interpreter␈α⊗for␈α⊗Extended␈α∃Lambda
␈↓ ↓H␈↓␈↓ βλCalculus', M.I.T. A.I. Memo 349, Dec. 1975. ␈↓↓[␈↓␈↓↓ 122␈↓␈↓↓ 157␈↓␈↓↓ 205␈↓␈↓↓ 339␈↓␈↓↓ 385␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Sus 76]␈↓ αxSussman,␈α+G.,␈α+and␈α+Steele,␈α+G.,␈α+`SCHEME␈α+Flash␈α, 1',␈α+M.I.T. A.I. Lab.,
␈↓ ↓H␈↓␈↓ βλJan. 1976. ␈↓↓[␈↓␈↓↓ 216␈↓␈↓↓ 236␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Tei 72]␈↓ αxTeitelman,␈α(W.,␈α(`Automated␈α(Programmering - The␈α(Programmer's␈α'Assistant',
␈↓ ↓H␈↓␈↓ βλProceedings of the Fall Joint Computer Conference, Dec. 1972. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ten 76]␈↓ αxTennent,␈α&R.,␈α&`The␈α&Denotational␈α&Semantics␈α&of␈α&Programming␈α&Languages',
␈↓ ↓H␈↓␈↓ βλ␈↓αComm. ACM 19␈↓, ␈↓↓8␈↓, p. 437-453, Aug. 1976. ␈↓↓[␈↓␈↓↓ 149␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Ter 75]␈↓ αxTerashima,␈α∪M.,␈α∪`Algorithms␈α∪Used␈α∀in␈α∪an␈α∪Implementation␈α∪of␈α∀HLISP',␈α∪Information
␈↓ ↓H␈↓␈↓ βλSciences Lab., TR 75-03, Univ. of Tokyo, Japan, Jan. 1975. ␈↓↓[␈↓␈↓↓ 254␈↓␈↓↓ 378␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Urm 76]␈↓ αxUrmi,␈αJ.,␈α
`A␈αShallow␈α
Binding␈αScheme␈αfor␈α
Fast␈αEnvironment␈α
Changing␈αin␈αa␈α
`Spaghetti
␈↓ ↓H␈↓␈↓ βλStack' LISP System', Linkoping University, Sweden, 1976. ␈↓↓[␈↓␈↓↓ 373␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Vui 74]␈↓ αxVuillemin,␈α∃J.,␈α∀`Correct␈α∃and␈α∀Optimal␈α∃Implementations␈α∀of␈α∃Recursion␈α∀in␈α∃a␈α∀Simple
␈↓ ↓H␈↓␈↓ βλProgramming␈α∩Language',␈α⊃␈↓αJournal␈α∩of␈α⊃Computer␈α∩and␈α⊃System␈α∩Science␈↓,␈α∩Vol 9,␈α⊃No 3,
␈↓ ↓H␈↓␈↓ βλDec 1974. ␈↓↓[␈↓␈↓↓ 207␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wad 71]␈↓ αxWadsworth,␈α⊃C.,␈α⊂`Semantics␈α⊃and␈α⊂Pragmatics␈α⊃of␈α⊂the␈α⊃Lambda-calculus',␈α⊃Ph.D.␈α⊂Thesis,
␈↓ ↓H␈↓␈↓ βλOxford University, 1971. ␈↓↓[␈↓␈↓↓ 158␈↓␈↓↓ 159␈↓␈↓↓ 160␈↓␈↓↓ 207␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wad 74a]␈↓ αxWadsworth,␈α∞C.,␈α
The␈α∞Relation␈α∞Between␈α
Lambda-expressions␈α∞and␈α∞Their␈α
Denotations',
␈↓ ↓H␈↓␈↓ βλunpublished paper, Systems and Info. Science Dept, Syracuse Univ., 1974. ␈↓↓[␈↓␈↓↓ 158␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wan 75]␈↓ αxWang,␈α≥P.,␈α≡`MACSYMA - A␈α≥Symbolic␈α≡Manipulation␈α≥System',␈α≡Proceedings␈α≥of
␈↓ ↓H␈↓␈↓ βλInternational Computer Symposium, Vol. 1, p. 103-109, 1975. ␈↓↓[␈↓␈↓↓ 366␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[War 74]␈↓ αxWard,␈α∃S.,␈α∃`Functional␈α∃Domains␈α∃of␈α∃Applicative␈α∃Languages',␈α∃Ph.D. Thesis,␈α∀M.I.T.,
␈↓ ↓H␈↓␈↓ βλMAC TR-136, Cambridge, Sep. 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Weg 68]␈↓ αxWegner,␈α P.,␈α ␈↓αProgramming␈α∨Languages,␈α Information␈α Structures␈α and␈α∨Machine
␈↓ ↓H␈↓α␈↓ βλOrganization␈↓, McGraw-Hill, New York, 1968. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓␈↓↓414 BIBLIOGRAPHY␈↓ 710.␈↓
␈↓ ↓H␈↓[Weg 70]␈↓ αxWegner,␈α≡P.,␈α≥`Three␈α≡Computer␈α≥Cultures␈α≡-␈α≥Computer␈α≡Technology,␈α≥Computer
␈↓ ↓H␈↓␈↓ βλMathematics␈α∂&␈α∞Computer␈α∂Science',␈α∞in␈α∂␈↓αAdvances␈α∞in␈α∂Computers␈↓,␈α∞␈↓↓10␈↓,␈α∂Academic␈α∞Press,
␈↓ ↓H␈↓␈↓ βλNew York, 1970. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Weg 71]␈↓ αxWegner,␈α→P.,␈α→`Data␈α→Structure␈α→Models␈α→for␈α→Programming␈α→Languages',␈α→p. 1-54␈α_in
␈↓ ↓H␈↓␈↓ βλ[DSIPL]. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Weg 72]␈↓ αxWegner,␈α∩P.,␈α∩`The␈α∩Vienna␈α∩Definition␈α∩Language',␈α∩␈↓αComputing␈α∩Surveys␈↓,␈α∩Vol 4,␈α∩No 1,
␈↓ ↓H␈↓␈↓ βλp. 5-63, Mar 1972. ␈↓↓[␈↓␈↓↓ 40␈↓␈↓↓ 148␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wegb 70]␈↓ αxWegbreit,␈αB.,␈α`Studies␈αin␈αExtensible␈αProgramming␈αLanguages',␈αPh.D.␈αThesis,␈α
Harvard
␈↓ ↓H␈↓␈↓ βλUniversity, Cambridge, Mass.,1970. ␈↓↓[␈↓␈↓↓ 377␈↓␈↓↓ 385␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wegb 71]␈↓ αxWegbreit,␈α∪B.,␈α∀`The␈α∪ECL␈α∀Programming␈α∪System',␈α∀Proceedings␈α∪AFIPS␈α∀1971␈α∪FJCC,
␈↓ ↓H␈↓␈↓ βλVol 39, AFIPS Press, Mondale, New Jersey, p. 253-262, 1971. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wegb 72]␈↓ αxWegbreit,␈α
B.,␈α
`A␈αGeneralized␈α
Compactifying␈α
Garbage␈αCollector',␈α
␈↓αComputer Journal 15␈↓,
␈↓ ↓H␈↓␈↓ βλ␈↓↓3␈↓, p. 204-208, Aug 1972. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wegb 74]␈↓ αxWegbreit,␈α
B.,␈α
`The␈α
Treatment␈α
of␈α
Data␈αTypes␈α
in␈α
EL1',␈α
␈↓αComm.␈α
ACM␈α
17␈↓,␈α
␈↓↓5␈↓,␈αp. 251-264,
␈↓ ↓H␈↓␈↓ βλMay 1974. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wegb 75]␈↓ αxWegbreit,␈α⊂B.,␈α⊂`Retrieval␈α∂From␈α⊂Context␈α⊂Trees',␈α∂␈↓αInformation␈α⊂Processing␈α⊂Letters,␈α⊂3␈↓,␈α∂␈↓↓4␈↓,
␈↓ ↓H␈↓␈↓ βλp. 119-120, March 1975. ␈↓↓[␈↓␈↓↓ 136␈↓␈↓↓ 280␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wei 62]␈↓ αxWeizenbaum,␈α↔J.,␈α↔`Knotted␈α↔List␈α_Structures',␈α↔␈↓αComm.␈α↔ACM 5␈↓,␈α↔␈↓↓13␈↓,␈α_p. 161-165,␈α↔Mar
␈↓ ↓H␈↓␈↓ βλ1962. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wei 63]␈↓ αxWeizenbaum,␈α↔J.,␈α↔`Symmetric␈α↔List␈α_Processor',␈α↔␈↓αComm.␈α↔ACM 6␈↓,␈α↔␈↓↓9␈↓,␈α_p. 524-544,␈α↔Sep
␈↓ ↓H␈↓␈↓ βλ1963. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wei 68]␈↓ αxWeizenbaum,␈α∩J.,␈α∩`The␈α⊃FUNARG␈α∩Problem␈α∩Explained',␈α∩unpublished␈α⊃memorandum,
␈↓ ↓H␈↓␈↓ βλM.I.T., Cambridge, Mass., 1968. ␈↓↓[␈↓␈↓↓ 116␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Weis 67]␈↓ αxWeismann, C., `LISP 1.5 Primer', Dickenson Press, Belmont, 1967. ␈↓↓[␈↓␈↓↓ norefs␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Win 75]␈↓ αxWinograd,␈α
T.,␈α`Breaking␈α
the␈αComplexity␈α
Barrier (again)',␈α␈↓αACM␈α
SIGPLAN␈α
Notes␈α10␈↓,
␈↓ ↓H␈↓␈↓ βλ␈↓↓1␈↓, p. 13-30, Jan. 1975. ␈↓↓[␈↓␈↓↓ 342␈↓␈↓↓ 377␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Wis 75]␈↓ αxWise, D., et. al., `Boolean-valued Loops', ␈↓αBIT␈↓ ␈↓↓15␈↓ p. 431-451, 1975. ␈↓↓[␈↓␈↓↓ 181␈↓␈↓↓ ]␈↓
␈↓ ↓H␈↓[Zil 70]␈↓ αxZilles,␈α
S.,␈α
`An␈α
Expansion␈α
of␈α
the␈α
Data␈α
Structuring␈α
Capabilities␈α
in␈α
PAL',␈α
M.S.␈αThesis,
␈↓ ↓H␈↓␈↓ βλMIT, Jun 1970. ␈↓↓[␈↓
␈↓ ↓H␈↓␈↓↓␈↓
∀INDEX 415␈↓
␈↓ ↓H␈↓␈↓αλ␈↓-notation 98 ␈↓ εh␈↓αPERIOD 252
␈↓ ↓H␈↓␈↓α=␈↓ 352 ␈↓ εh␈↓αPNAME 248
␈↓ ↓H␈↓␈↓αand␈↓ 140, 338 ␈↓ εh␈↓αprin0 254
␈↓ ↓H␈↓␈↓αappend␈↓ 46 ␈↓ εh␈↓αprint 254
␈↓ ↓H␈↓␈↓αapply␈↓ 104 ␈↓ εh␈↓αprog 171
␈↓ ↓H␈↓␈↓αarray␈↓ 350 ␈↓ εh␈↓αputprop 242, 363
␈↓ ↓H␈↓␈↓αatom␈↓ 18 ␈↓ εh␈↓αQUOTE 94
␈↓ ↓H␈↓␈↓αBLANK␈↓ 252 ␈↓ εh␈↓αratom 252, 256, 258, 363
␈↓ ↓H␈↓␈↓αcar␈↓ 13 ␈↓ εh␈↓αread_head 253
␈↓ ↓H␈↓␈↓αcar-cdr-␈↓chains 14 ␈↓ εh␈↓αread_tail 253
␈↓ ↓H␈↓␈↓αcatch␈↓ 184 ␈↓ εh␈↓αread 253
␈↓ ↓H␈↓␈↓αcdr␈↓ 13 ␈↓ εh␈↓αread␈↓ macro 260
␈↓ ↓H␈↓␈↓αcdr␈↓-coding 374 ␈↓ εh␈↓␈↓αremprop␈↓ 243, 363
␈↓ ↓H␈↓␈↓αchar␈↓ 352 ␈↓ εh␈↓␈↓αrest␈↓ 28, 352
␈↓ ↓H␈↓␈↓αcompile␈↓ 285 ␈↓ εh␈↓␈↓αRPAR␈↓ 252
␈↓ ↓H␈↓␈↓αconcat␈↓ 28, 352 ␈↓ εh␈↓␈↓αrplaca␈↓ 360
␈↓ ↓H␈↓␈↓αCOND␈↓ 95, 103 ␈↓ εh␈↓␈↓αrplacd␈↓ 360
␈↓ ↓H␈↓␈↓αcons␈↓ 12, 261 ␈↓ εh␈↓␈↓αseq␈↓ 28
␈↓ ↓H␈↓␈↓αdeposit␈↓ 309 ␈↓ εh␈↓␈↓αstore␈↓ 350
␈↓ ↓H␈↓␈↓αeq␈↓ 19 ␈↓ εh␈↓␈↓αtgmoaf␈↓ 83, 301
␈↓ ↓H␈↓␈↓αequal␈↓ 23 ␈↓ εh␈↓␈↓αtgmoaf␈↓ 396
␈↓ ↓H␈↓␈↓αerr␈↓ 184 ␈↓ εh␈↓␈↓αtgmoafr␈↓ 83, 301
␈↓ ↓H␈↓␈↓αerrset␈↓ 184 ␈↓ εh␈↓␈↓αthrow␈↓ 184
␈↓ ↓H␈↓␈↓αeval␈↓ 102, 223, 301, 386 ␈↓ εh␈↓␈↓εa␈↓-rule 156
␈↓ ↓H␈↓␈↓αevcond␈↓ 103 ␈↓ εh␈↓␈↓εb␈↓-rule 156
␈↓ ↓H␈↓␈↓αexamine␈↓ 309 ␈↓ εh␈↓␈↓ SM␈↓ 290
␈↓ ↓H␈↓␈↓αfirst␈↓ 352 ␈↓ εh␈↓a-lists 97
␈↓ ↓H␈↓␈↓αFUNARG␈↓ 131 ␈↓ εh␈↓access chain 117
␈↓ ↓H␈↓␈↓αfunction␈↓ 126 ␈↓ εh␈↓access link 117
␈↓ ↓H␈↓␈↓αgensym␈↓ 305 ␈↓ εh␈↓accumulators 44
␈↓ ↓H␈↓␈↓αget␈↓ 242 ␈↓ εh␈↓activation environment 132
␈↓ ↓H␈↓␈↓αgetl␈↓ 242 ␈↓ εh␈↓actual parameters 15
␈↓ ↓H␈↓␈↓αgo␈↓ 174 ␈↓ εh␈↓AMBIT/G 234
␈↓ ↓H␈↓␈↓αisseq␈↓ 27 ␈↓ εh␈↓analytic syntax 150
␈↓ ↓H␈↓␈↓αlabel␈↓ 121 ␈↓ εh␈↓applicative language 15
␈↓ ↓H␈↓␈↓αlist 33 ␈↓ εh␈↓Assemblers 298
␈↓ ↓H␈↓αLPAR 252 ␈↓ εh␈↓association lists 97
␈↓ ↓H␈↓αmaplist 134 ␈↓ εh␈↓atom header 247
␈↓ ↓H␈↓αmkent 97 ␈↓ εh␈↓atom space 226
␈↓ ↓H␈↓αNIL 32, 251 ␈↓ εh␈↓auxiliary function 44
␈↓ ↓H␈↓αnull 27, 352 ␈↓ εh␈↓base language 380
␈↓ ↓H␈↓αOBLIST 257 ␈↓ εh␈↓Binary Program Space 297
␈↓ ↓H␈↓αor 140 ␈↓ εh␈↓binding environment 132
␈↓ ↓H␈↓αpatom 252 ␈↓ εh␈↓binding strategy 135
␈↓ ↓H␈↓␈↓↓416 INDEX␈↓ X␈↓
␈↓ ↓H␈↓bootstrapping 286 ␈↓ εh␈↓fluid variable 116
␈↓ ↓H␈↓bound variable 115, 155 ␈↓ εh␈↓form 17, 99
␈↓ ↓H␈↓box-notation 9 ␈↓ εh␈↓formal parameter 14
␈↓ ↓H␈↓BPS 298 ␈↓ εh␈↓forms 12
␈↓ ↓H␈↓bucket hashing 256 ␈↓ εh␈↓forward reference 307
␈↓ ↓H␈↓cache value cells 281 ␈↓ εh␈↓free space list 261
␈↓ ↓H␈↓call-by-name 90, 206 ␈↓ εh␈↓free variable 115, 155
␈↓ ↓H␈↓call-by-need 207 ␈↓ εh␈↓Full Word Space 249
␈↓ ↓H␈↓call-by-value 90 ␈↓ εh␈↓funarg 127
␈↓ ↓H␈↓case statement 179 ␈↓ εh␈↓function 99
␈↓ ↓H␈↓case statement 143 ␈↓ εh␈↓function application 15
␈↓ ↓H␈↓closure 127, 178 ␈↓ εh␈↓functional argument 123
␈↓ ↓H␈↓code generators 286 ␈↓ εh␈↓functional composition 13
␈↓ ↓H␈↓coercion 224 ␈↓ εh␈↓functional value 129
␈↓ ↓H␈↓collision 256 ␈↓ εh␈↓FWS 249
␈↓ ↓H␈↓compiler 314, 317 ␈↓ εh␈↓garbage collection 263, 352
␈↓ ↓H␈↓computed function 144 ␈↓ εh␈↓garbage collector 262, 350, 363
␈↓ ↓H␈↓concrete syntax 150 ␈↓ εh␈↓generalized control structures 182
␈↓ ↓H␈↓conditional expression 18, 19, 103 ␈↓ εh␈↓generative definition 3
␈↓ ↓H␈↓CONNIVER 386 ␈↓ εh␈↓global variable 114, 116
␈↓ ↓H␈↓constructor 12 ␈↓ εh␈↓halting problem 166
␈↓ ↓H␈↓continuation 192 ␈↓ εh␈↓hash consing 267, 361, 377
␈↓ ↓H␈↓control environment 128 ␈↓ εh␈↓hashing 256
␈↓ ↓H␈↓control structures 37 ␈↓ εh␈↓hashing algorithm 256
␈↓ ↓H␈↓deep binding 138 ␈↓ εh␈↓inductive definition 3
␈↓ ↓H␈↓definition by recursion 41 ␈↓ εh␈↓internal lambdas 101
␈↓ ↓H␈↓denotational 152 ␈↓ εh␈↓inums 365
␈↓ ↓H␈↓differentiation 53 ␈↓ εh␈↓invisible pointers 376
␈↓ ↓H␈↓discriminator 18 ␈↓ εh␈↓lambda list 99
␈↓ ↓H␈↓dope vector 349 ␈↓ εh␈↓length 172
␈↓ ↓H␈↓dotted-pair 6 ␈↓ εh␈↓lexical binding 136
␈↓ ↓H␈↓double-linking 368 ␈↓ εh␈↓linear LISP 351
␈↓ ↓H␈↓doubly-linked list structure 228 ␈↓ εh␈↓linear search 97
␈↓ ↓H␈↓dynamic binding 116 ␈↓ εh␈↓linked allocation 271
␈↓ ↓H␈↓EL1 380 ␈↓ εh␈↓linked list structure 227
␈↓ ↓H␈↓evaluation 13, 88 ␈↓ εh␈↓LISP machine 269
␈↓ ↓H␈↓examples of ␈↓αeval␈↓ 106 ␈↓ εh␈↓list terminator 32
␈↓ ↓H␈↓expr 210 ␈↓ εh␈↓list-notation 32
␈↓ ↓H␈↓extensible language 380 ␈↓ εh␈↓lists 30
␈↓ ↓H␈↓fexpr 210 ␈↓ εh␈↓literal atoms 5
␈↓ ↓H␈↓Fibonacci sequence 43 ␈↓ εh␈↓local binding 114
␈↓ ↓H␈↓fix-up 307 ␈↓ εh␈↓local symbol table 114
␈↓ ↓H␈↓fixed points 218 ␈↓ εh␈↓local variable 172
␈↓ ↓H␈↓fixed-point operator 220 ␈↓ εh␈↓M-expr LISP 96
␈↓ ↓H␈↓␈↓↓␈↓
∀INDEX 417␈↓
␈↓ ↓H␈↓M-expressions 222 ␈↓ εh␈↓scanner 252
␈↓ ↓H␈↓macros 336 ␈↓ εh␈↓SDIO 396
␈↓ ↓H␈↓mapping functions 134 ␈↓ εh␈↓selector 13
␈↓ ↓H␈↓marking phase 263 ␈↓ εh␈↓self-applicative 159
␈↓ ↓H␈↓match-variable 6 ␈↓ εh␈↓self-applicative functions 135
␈↓ ↓H␈↓meta-language 96, 222 ␈↓ εh␈↓shallow binding 138
␈↓ ↓H␈↓meta-variables 6 ␈↓ εh␈↓singly linked 227
␈↓ ↓H␈↓MICRO-PLANNER 386 ␈↓ εh␈↓Special Form 140
␈↓ ↓H␈↓modular programming 344 ␈↓ εh␈↓special forms 102
␈↓ ↓H␈↓mother-vector 349 ␈↓ εh␈↓special variable 338
␈↓ ↓H␈↓MUDDLE 386 ␈↓ εh␈↓stack 271
␈↓ ↓H␈↓name stack 272 ␈↓ εh␈↓stack synchronization 293
␈↓ ↓H␈↓non-local 114 ␈↓ εh␈↓static binding 136
␈↓ ↓H␈↓non-local variables 338 ␈↓ εh␈↓storage reclaimer 262
␈↓ ↓H␈↓non-strict 21 ␈↓ εh␈↓stratification 399
␈↓ ↓H␈↓numbers 364 ␈↓ εh␈↓strict functions 12
␈↓ ↓H␈↓object list 257 ␈↓ εh␈↓string space 351
␈↓ ↓H␈↓offset 317 ␈↓ εh␈↓string processor 351
␈↓ ↓H␈↓open addressing 256 ␈↓ εh␈↓string space pointer 352
␈↓ ↓H␈↓open function 219 ␈↓ εh␈↓sweep phase 264
␈↓ ↓H␈↓operation code 299 ␈↓ εh␈↓symbol tables 96, 299
␈↓ ↓H␈↓operational 152 ␈↓ εh␈↓Symbolic expressions 5
␈↓ ↓H␈↓p-list 247 ␈↓ εh␈↓syntax-directed 391
␈↓ ↓H␈↓parser 252 ␈↓ εh␈↓table-driven 176
␈↓ ↓H␈↓partial application 146 ␈↓ εh␈↓termination conditions 42
␈↓ ↓H␈↓partial function 11, 13 ␈↓ εh␈↓threading 368
␈↓ ↓H␈↓pattern directed invocation 66 ␈↓ εh␈↓total function 11
␈↓ ↓H␈↓PL/1 380 ␈↓ εh␈↓type fault 22
␈↓ ↓H␈↓pointer 226 ␈↓ εh␈↓unbound variable 115
␈↓ ↓H␈↓pointer space 226 ␈↓ εh␈↓universal function 167
␈↓ ↓H␈↓polymorphic functions 28 ␈↓ εh␈↓value stack 272, 315
␈↓ ↓H␈↓precedence 391 ␈↓ εh␈↓value cell 138
␈↓ ↓H␈↓predicates 18 ␈↓ εh␈↓variables 114
␈↓ ↓H␈↓prefix notation 54
␈↓ ↓H␈↓print-name 248
␈↓ ↓H␈↓property-list 237
␈↓ ↓H␈↓recognizer 18, 27
␈↓ ↓H␈↓record 358
␈↓ ↓H␈↓reduction rule 158
␈↓ ↓H␈↓reference counter 267, 280
␈↓ ↓H␈↓referential transparency 156
␈↓ ↓H␈↓S-expr LISP 96
␈↓ ↓H␈↓S-expressions 5
␈↓ ↓H␈↓S-exprs 5